// Copyright 2020 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 debug_test

// Provide 'static type checking' of the templates. This guards against changes in various
// gopls datastructures causing template execution to fail. The checking is done by
// the github.com/jba/templatecheck package. Before that is run, the test checks that
// its list of templates and their arguments corresponds to the arguments in
// calls to render(). The test assumes that all uses of templates are done through render().

import (
	"go/ast"
	"html/template"
	"os"
	"runtime"
	"strings"
	"testing"

	"github.com/jba/templatecheck"
	"golang.org/x/tools/go/packages"
	"golang.org/x/tools/gopls/internal/cache"
	"golang.org/x/tools/gopls/internal/debug"
	"golang.org/x/tools/gopls/internal/file"
	"golang.org/x/tools/gopls/internal/util/moremaps"
	"golang.org/x/tools/internal/testenv"
)

var templates = map[string]struct {
	tmpl *template.Template
	data any // a value of the needed type
}{
	"MainTmpl":    {debug.MainTmpl, &debug.Instance{}},
	"DebugTmpl":   {debug.DebugTmpl, nil},
	"RPCTmpl":     {debug.RPCTmpl, &debug.Rpcs{}},
	"TraceTmpl":   {debug.TraceTmpl, debug.TraceResults{}},
	"CacheTmpl":   {debug.CacheTmpl, &cache.Cache{}},
	"SessionTmpl": {debug.SessionTmpl, &cache.Session{}},
	"ClientTmpl":  {debug.ClientTmpl, &debug.Client{}},
	"ServerTmpl":  {debug.ServerTmpl, &debug.Server{}},
	"FileTmpl": {debug.FileTmpl, *new(interface {
		file.Handle
		Kind() file.Kind // (overlay files only)
	})},
	"InfoTmpl":     {debug.InfoTmpl, "something"},
	"MemoryTmpl":   {debug.MemoryTmpl, runtime.MemStats{}},
	"AnalysisTmpl": {debug.AnalysisTmpl, new(debug.State).Analysis()},
}

func TestTemplates(t *testing.T) {
	testenv.NeedsGoPackages(t)
	testenv.NeedsLocalXTools(t)

	cfg := &packages.Config{
		Mode: packages.NeedTypes | packages.NeedSyntax | packages.NeedTypesInfo,
	}
	cfg.Env = os.Environ()
	cfg.Env = append(cfg.Env,
		"GOPACKAGESDRIVER=off",
		"GOWORK=off", // necessary for -mod=mod below
		"GOFLAGS=-mod=mod",
	)

	pkgs, err := packages.Load(cfg, "golang.org/x/tools/gopls/internal/debug")
	if err != nil {
		t.Fatal(err)
	}
	if len(pkgs) != 1 {
		t.Fatalf("expected a single package, but got %d", len(pkgs))
	}
	p := pkgs[0]
	if len(p.Errors) != 0 {
		t.Fatalf("compiler error, e.g. %v", p.Errors[0])
	}
	// find the calls to render in serve.go
	tree := treeOf(p, "serve.go")
	if tree == nil {
		t.Fatalf("found no syntax tree for %s", "serve.go")
	}
	renders := callsOf(tree, "render")
	if len(renders) == 0 {
		t.Fatalf("found no calls to render")
	}
	var found = make(map[string]bool)
	for _, r := range renders {
		if len(r.Args) != 2 {
			// template, func
			t.Fatalf("got %d args, expected 2", len(r.Args))
		}
		t0, ok := p.TypesInfo.Types[r.Args[0]]
		if !ok || !t0.IsValue() || t0.Type.String() != "*html/template.Template" {
			t.Fatalf("no type info for template")
		}
		if id, ok := r.Args[0].(*ast.Ident); !ok {
			t.Errorf("expected *ast.Ident, got %T", r.Args[0])
		} else {
			found[id.Name] = true
		}
	}
	// make sure found and templates have the same templates
	for k := range found {
		if _, ok := templates[k]; !ok {
			t.Errorf("code has template %s, but test does not", k)
		}
	}
	for k := range templates {
		if _, ok := found[k]; !ok {
			t.Errorf("test has template %s, code does not", k)
		}
	}
	// now check all the known templates, in alphabetic order, for determinacy
	for k, v := range moremaps.Sorted(templates) {
		// the FuncMap is an annoyance; should not be necessary
		if err := templatecheck.CheckHTML(v.tmpl, v.data); err != nil {
			t.Errorf("%s: %v", k, err)
			continue
		}
		t.Logf("%s ok", k)
	}
}

func callsOf(tree *ast.File, name string) []*ast.CallExpr {
	var ans []*ast.CallExpr
	f := func(n ast.Node) bool {
		x, ok := n.(*ast.CallExpr)
		if !ok {
			return true
		}
		if y, ok := x.Fun.(*ast.Ident); ok {
			if y.Name == name {
				ans = append(ans, x)
			}
		}
		return true
	}
	ast.Inspect(tree, f)
	return ans
}

func treeOf(p *packages.Package, fname string) *ast.File {
	for _, tree := range p.Syntax {
		loc := tree.Package
		pos := p.Fset.PositionFor(loc, false)
		if strings.HasSuffix(pos.Filename, fname) {
			return tree
		}
	}
	return nil
}
