// Copyright 2012 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 doc

import (
	"bytes"
	"flag"
	"fmt"
	"io/fs"
	"os"
	"path/filepath"
	"regexp"
	"strings"
	"testing"
	"text/template"

	"golang.org/x/website/internal/backport/go/ast"
	"golang.org/x/website/internal/backport/go/parser"
	"golang.org/x/website/internal/backport/go/printer"
	"golang.org/x/website/internal/backport/go/token"
)

var update = flag.Bool("update", false, "update golden (.out) files")
var files = flag.String("files", "", "consider only Go test files matching this regular expression")

const dataDir = "testdata"

var templateTxt = readTemplate("template.txt")

func readTemplate(filename string) *template.Template {
	t := template.New(filename)
	t.Funcs(template.FuncMap{
		"node":     nodeFmt,
		"synopsis": synopsisFmt,
		"indent":   indentFmt,
	})
	return template.Must(t.ParseFiles(filepath.Join(dataDir, filename)))
}

func nodeFmt(node interface{}, fset *token.FileSet) string {
	var buf bytes.Buffer
	printer.Fprint(&buf, fset, node)
	return strings.ReplaceAll(strings.TrimSpace(buf.String()), "\n", "\n\t")
}

func synopsisFmt(s string) string {
	const n = 64
	if len(s) > n {
		// cut off excess text and go back to a word boundary
		s = s[0:n]
		if i := strings.LastIndexAny(s, "\t\n "); i >= 0 {
			s = s[0:i]
		}
		s = strings.TrimSpace(s) + " ..."
	}
	return "// " + strings.ReplaceAll(s, "\n", " ")
}

func indentFmt(indent, s string) string {
	end := ""
	if strings.HasSuffix(s, "\n") {
		end = "\n"
		s = s[:len(s)-1]
	}
	return indent + strings.ReplaceAll(s, "\n", "\n"+indent) + end
}

func isGoFile(fi fs.FileInfo) bool {
	name := fi.Name()
	return !fi.IsDir() &&
		len(name) > 0 && name[0] != '.' && // ignore .files
		filepath.Ext(name) == ".go"
}

type bundle struct {
	*Package
	FSet *token.FileSet
}

func test(t *testing.T, mode Mode) {
	// determine file filter
	filter := isGoFile
	if *files != "" {
		rx, err := regexp.Compile(*files)
		if err != nil {
			t.Fatal(err)
		}
		filter = func(fi fs.FileInfo) bool {
			return isGoFile(fi) && rx.MatchString(fi.Name())
		}
	}

	// get packages
	fset := token.NewFileSet()
	pkgs, err := parser.ParseDir(fset, dataDir, filter, parser.ParseComments)
	if err != nil {
		t.Fatal(err)
	}

	// test packages
	for _, pkg := range pkgs {
		t.Run(pkg.Name, func(t *testing.T) {
			importPath := dataDir + "/" + pkg.Name
			var files []*ast.File
			for _, f := range pkg.Files {
				files = append(files, f)
			}
			doc, err := NewFromFiles(fset, files, importPath, mode)
			if err != nil {
				t.Fatal(err)
			}

			// golden files always use / in filenames - canonicalize them
			for i, filename := range doc.Filenames {
				doc.Filenames[i] = filepath.ToSlash(filename)
			}

			// print documentation
			var buf bytes.Buffer
			if err := templateTxt.Execute(&buf, bundle{doc, fset}); err != nil {
				t.Fatal(err)
			}
			got := buf.Bytes()

			// update golden file if necessary
			golden := filepath.Join(dataDir, fmt.Sprintf("%s.%d.golden", pkg.Name, mode))
			if *update {
				err := os.WriteFile(golden, got, 0644)
				if err != nil {
					t.Fatal(err)
				}
			}

			// get golden file
			want, err := os.ReadFile(golden)
			if err != nil {
				t.Fatal(err)
			}

			// compare
			if !bytes.Equal(got, want) {
				t.Errorf("package %s\n\tgot:\n%s\n\twant:\n%s", pkg.Name, got, want)
			}
		})
	}
}

func Test(t *testing.T) {
	t.Run("default", func(t *testing.T) { test(t, 0) })
	t.Run("AllDecls", func(t *testing.T) { test(t, AllDecls) })
	t.Run("AllMethods", func(t *testing.T) { test(t, AllMethods) })
}

func TestAnchorID(t *testing.T) {
	const in = "Important Things 2 Know & Stuff"
	const want = "hdr-Important_Things_2_Know___Stuff"
	got := anchorID(in)
	if got != want {
		t.Errorf("anchorID(%q) = %q; want %q", in, got, want)
	}
}

const funcsTestFile = `
package funcs

func F() {}

type S1 struct {
	S2  // embedded, exported
	s3  // embedded, unexported
}

func NewS1()  S1 {return S1{} }
func NewS1p() *S1 { return &S1{} }

func (S1) M1() {}
func (r S1) M2() {}
func(S1) m3() {}		// unexported not shown
func (*S1) P1() {}		// pointer receiver

type S2 int
func (S2) M3() {}		// shown on S2

type s3 int
func (s3) M4() {}		// shown on S1

type G1[T any] struct {
	*s3
}

func NewG1[T any]() G1[T] { return G1[T]{} }

func (G1[T]) MG1() {}
func (*G1[U]) MG2() {}

type G2[T, U any] struct {}

func NewG2[T, U any]() G2[T, U] { return G2[T, U]{} }

func (G2[T, U]) MG3() {}
func (*G2[A, B]) MG4() {}


`

var funcsPackage = &Package{
	Funcs: []*Func{{Name: "F"}},
	Types: []*Type{
		{
			Name:  "G1",
			Funcs: []*Func{{Name: "NewG1"}},
			Methods: []*Func{
				{Name: "M4", Recv: "G1", // TODO: synthesize a param for G1?
					Orig: "s3", Level: 1},
				{Name: "MG1", Recv: "G1[T]", Orig: "G1[T]", Level: 0},
				{Name: "MG2", Recv: "*G1[U]", Orig: "*G1[U]", Level: 0},
			},
		},
		{
			Name:  "G2",
			Funcs: []*Func{{Name: "NewG2"}},
			Methods: []*Func{
				{Name: "MG3", Recv: "G2[T, U]", Orig: "G2[T, U]", Level: 0},
				{Name: "MG4", Recv: "*G2[A, B]", Orig: "*G2[A, B]", Level: 0},
			},
		},
		{
			Name:  "S1",
			Funcs: []*Func{{Name: "NewS1"}, {Name: "NewS1p"}},
			Methods: []*Func{
				{Name: "M1", Recv: "S1", Orig: "S1", Level: 0},
				{Name: "M2", Recv: "S1", Orig: "S1", Level: 0},
				{Name: "M4", Recv: "S1", Orig: "s3", Level: 1},
				{Name: "P1", Recv: "*S1", Orig: "*S1", Level: 0},
			},
		},
		{
			Name: "S2",
			Methods: []*Func{
				{Name: "M3", Recv: "S2", Orig: "S2", Level: 0},
			},
		},
	},
}
