// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package godoc

import (
	"go/doc"
	"net/http"
	"net/http/httptest"
	"net/url"
	"sort"
	"strings"
	"testing"
	"text/template"

	"golang.org/x/tools/godoc/vfs/mapfs"
)

// TestIgnoredGoFiles tests the scenario where a folder has no .go or .c files,
// but has an ignored go file.
func TestIgnoredGoFiles(t *testing.T) {
	packagePath := "github.com/package"
	packageComment := "main is documented in an ignored .go file"

	c := NewCorpus(mapfs.New(map[string]string{
		"src/" + packagePath + "/ignored.go": `// +build ignore

// ` + packageComment + `
package main`}))
	srv := &handlerServer{
		p: &Presentation{
			Corpus: c,
		},
		c: c,
	}
	pInfo := srv.GetPageInfo("/src/"+packagePath, packagePath, NoFiltering, "linux", "amd64")

	if pInfo.PDoc == nil {
		t.Error("pInfo.PDoc = nil; want non-nil.")
	} else {
		if got, want := pInfo.PDoc.Doc, packageComment+"\n"; got != want {
			t.Errorf("pInfo.PDoc.Doc = %q; want %q.", got, want)
		}
		if got, want := pInfo.PDoc.Name, "main"; got != want {
			t.Errorf("pInfo.PDoc.Name = %q; want %q.", got, want)
		}
		if got, want := pInfo.PDoc.ImportPath, packagePath; got != want {
			t.Errorf("pInfo.PDoc.ImportPath = %q; want %q.", got, want)
		}
	}
	if pInfo.FSet == nil {
		t.Error("pInfo.FSet = nil; want non-nil.")
	}
}

func TestIssue5247(t *testing.T) {
	const packagePath = "example.com/p"
	c := NewCorpus(mapfs.New(map[string]string{
		"src/" + packagePath + "/p.go": `package p

//line notgen.go:3
// F doc //line 1 should appear
// line 2 should appear
func F()
//line foo.go:100`})) // No newline at end to check corner cases.

	srv := &handlerServer{
		p: &Presentation{Corpus: c},
		c: c,
	}
	pInfo := srv.GetPageInfo("/src/"+packagePath, packagePath, 0, "linux", "amd64")
	if got, want := pInfo.PDoc.Funcs[0].Doc, "F doc //line 1 should appear\nline 2 should appear\n"; got != want {
		t.Errorf("pInfo.PDoc.Funcs[0].Doc = %q; want %q", got, want)
	}
}

func testServeBody(t *testing.T, p *Presentation, path, body string) {
	t.Helper()
	r := &http.Request{URL: &url.URL{Path: path}}
	rw := httptest.NewRecorder()
	p.ServeFile(rw, r)
	if rw.Code != 200 || !strings.Contains(rw.Body.String(), body) {
		t.Fatalf("GET %s: expected 200 w/ %q: got %d w/ body:\n%s",
			path, body, rw.Code, rw.Body)
	}
}

func TestRedirectAndMetadata(t *testing.T) {
	c := NewCorpus(mapfs.New(map[string]string{
		"doc/y/index.html": "Hello, y.",
		"doc/x/index.html": `<!--{
		"Path": "/doc/x/"
}-->

Hello, x.
`}))
	c.updateMetadata()
	p := &Presentation{
		Corpus:    c,
		GodocHTML: template.Must(template.New("").Parse(`{{printf "%s" .Body}}`)),
	}

	// Test that redirect is sent back correctly.
	// Used to panic. See golang.org/issue/40665.
	for _, elem := range []string{"x", "y"} {
		dir := "/doc/" + elem + "/"

		r := &http.Request{URL: &url.URL{Path: dir + "index.html"}}
		rw := httptest.NewRecorder()
		p.ServeFile(rw, r)
		loc := rw.Result().Header.Get("Location")
		if rw.Code != 301 || loc != dir {
			t.Errorf("GET %s: expected 301 -> %q, got %d -> %q", r.URL.Path, dir, rw.Code, loc)
		}

		testServeBody(t, p, dir, "Hello, "+elem)
	}
}

func TestMarkdown(t *testing.T) {
	p := &Presentation{
		Corpus: NewCorpus(mapfs.New(map[string]string{
			"doc/test.md":  "**bold**",
			"doc/test2.md": `{{"*template*"}}`,
		})),
		GodocHTML: template.Must(template.New("").Parse(`{{printf "%s" .Body}}`)),
	}

	testServeBody(t, p, "/doc/test.html", "<strong>bold</strong>")
	testServeBody(t, p, "/doc/test2.html", "<em>template</em>")
}

func TestGenerics(t *testing.T) {
	c := NewCorpus(mapfs.New(map[string]string{
		"blah/blah.go": `package blah

var A AStruct[int]

type AStruct[T any] struct {
	A string
	X T
}

func (a *AStruct[T]) Method() T {
	return a.X
}

func (a AStruct[T]) NonPointerMethod() T {
	return a.X
}

func NewAStruct[T any](arg T) *AStruct[T] {
	return &AStruct[T]{ X: arg }
}

type NonGenericStruct struct {
	B int
}

func (b *NonGenericStruct) NonGenericMethod() int {
	return b.B
}

func NewNonGenericStruct(arg int) *NonGenericStruct {
	return &NonGenericStruct{arg}
}

type Pair[K, V any] struct {
	K K
	V V
}

func (p Pair[K, V]) Apply(kf func(K) K, vf func(V) V) Pair[K, V] {
	return &Pair{ K: kf(p.K), V: vf(p.V) }
}

func (p *Pair[K, V]) Set(k K, v V) {
	p.K = k
	p.V = v
}

func NewPair[K, V any](k K, v V) Pair[K, V] {
	return Pair[K, V]{ k, v }
}
`}))

	srv := &handlerServer{
		p: &Presentation{
			Corpus: c,
		},
		c: c,
	}
	pInfo := srv.GetPageInfo("/blah/", "", NoFiltering, "linux", "amd64")
	t.Logf("%v\n", pInfo)

	findType := func(name string) *doc.Type {
		for _, typ := range pInfo.PDoc.Types {
			if typ.Name == name {
				return typ
			}
		}
		return nil
	}

	assertFuncs := func(typ *doc.Type, typFuncs []*doc.Func, funcs ...string) {
		typfuncs := make([]string, len(typFuncs))
		for i := range typFuncs {
			typfuncs[i] = typFuncs[i].Name
		}
		sort.Strings(typfuncs)
		sort.Strings(funcs)
		if len(typfuncs) != len(funcs) {
			t.Errorf("function mismatch for type %q, got: %q, want: %q", typ.Name, typfuncs, funcs)
			return
		}
		for i := range funcs {
			if funcs[i] != typfuncs[i] {
				t.Errorf("function mismatch for type %q: got: %q, want: %q", typ.Name, typfuncs, funcs)
				return
			}
		}
	}

	aStructType := findType("AStruct")
	assertFuncs(aStructType, aStructType.Funcs, "NewAStruct")
	assertFuncs(aStructType, aStructType.Methods, "Method", "NonPointerMethod")

	nonGenericStructType := findType("NonGenericStruct")
	assertFuncs(nonGenericStructType, nonGenericStructType.Funcs, "NewNonGenericStruct")
	assertFuncs(nonGenericStructType, nonGenericStructType.Methods, "NonGenericMethod")

	pairType := findType("Pair")
	assertFuncs(pairType, pairType.Funcs, "NewPair")
	assertFuncs(pairType, pairType.Methods, "Apply", "Set")

	if len(pInfo.PDoc.Funcs) > 0 {
		t.Errorf("unexpected functions in package documentation")
	}
}
