// 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 is various
// gopls datastructures causing template execution to fail. The checking is done by
// the github.com/jba/templatecheck pacakge. 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"
	"log"
	"runtime"
	"sort"
	"strings"
	"testing"

	"github.com/jba/templatecheck"
	"golang.org/x/tools/go/packages"
	"golang.org/x/tools/internal/lsp/cache"
	"golang.org/x/tools/internal/lsp/debug"
	"golang.org/x/tools/internal/lsp/source"
	"golang.org/x/tools/internal/span"
)

type tdata struct {
	tmpl *template.Template
	data interface{} // a value of the needed type
}

var templates = map[string]tdata{
	"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{}},
	"ViewTmpl":    {debug.ViewTmpl, &cache.View{}},
	"ClientTmpl":  {debug.ClientTmpl, &debug.Client{}},
	"ServerTmpl":  {debug.ServerTmpl, &debug.Server{}},
	//"FileTmpl":    {FileTmpl, source.Overlay{}}, // need to construct a source.Overlay in init
	"InfoTmpl":   {debug.InfoTmpl, "something"},
	"MemoryTmpl": {debug.MemoryTmpl, runtime.MemStats{}},
}

// construct a source.Overlay for fileTmpl
type fakeOverlay struct{}

func (fakeOverlay) Version() float64 {
	return 0
}
func (fakeOverlay) Session() string {
	return ""
}
func (fakeOverlay) VersionedFileIdentity() source.VersionedFileIdentity {
	return source.VersionedFileIdentity{}
}
func (fakeOverlay) FileIdentity() source.FileIdentity {
	return source.FileIdentity{}
}
func (fakeOverlay) Kind() source.FileKind {
	return 0
}
func (fakeOverlay) Read() ([]byte, error) {
	return nil, nil
}
func (fakeOverlay) Saved() bool {
	return true
}
func (fakeOverlay) URI() span.URI {
	return ""
}

var _ source.Overlay = fakeOverlay{}

func init() {
	log.SetFlags(log.Lshortfile)
	var v fakeOverlay
	templates["FileTmpl"] = tdata{debug.FileTmpl, v}
}

func TestTemplates(t *testing.T) {
	if runtime.GOOS == "android" {
		t.Skip("this test is not supported for Android")
	}
	cfg := &packages.Config{
		Mode: packages.NeedTypesInfo | packages.LoadAllSyntax, // figure out what's necessary PJW
	}
	pkgs, err := packages.Load(cfg, "golang.org/x/tools/internal/lsp/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(p, 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
	keys := []string{}
	for k := range templates {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	for _, k := range keys {
		v := templates[k]
		// 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)
		}
	}
}

func callsOf(p *packages.Package, 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
}
