// 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.

// The helper command generates the declaration of the concrete
// 'server' type that implements the abstract Server interface defined
// in protocol/tsserver.go (which is itself generated from the LSP
// protocol).
//
// To run, invoke "go generate" in the parent (lsp) directory.
//
// TODO(adonovan): merge this into the main LSP generator.
package main

import (
	"bytes"
	"flag"
	"fmt"
	"go/ast"
	"go/format"
	"go/parser"
	"go/token"
	"log"
	"os"
	"sort"
	"strings"
	"text/template"
)

var (
	typ = flag.String("t", "Server", "generate code for this type")
	def = flag.String("d", "", "the file the type is defined in") // this relies on punning
	use = flag.String("u", "", "look for uses in this package")
	out = flag.String("o", "", "where to write the generated file")
)

func main() {
	log.SetFlags(log.Lshortfile)
	flag.Parse()
	if *typ == "" || *def == "" || *use == "" || *out == "" {
		flag.PrintDefaults()
		os.Exit(1)
	}
	// read the type definition and see what methods we're looking for
	doTypes()

	// parse the package and see which methods are defined
	doUses()

	output()
}

// replace "\\\n" with nothing before using
var tmpl = `// Copyright 2021 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 lsp

// Code generated by gopls/internal/lsp/helper. DO NOT EDIT.

import (
	"context"

	"golang.org/x/tools/gopls/internal/lsp/protocol"
)

{{range $key, $v := .Stuff}}
func (s *{{$.Type}}) {{$v.Name}}({{.Param}}) {{.Result}} {
	{{if ne .Found ""}} return s.{{.Internal}}({{.Invoke}})\
	{{else}}return {{if lt 1 (len .Results)}}nil, {{end}}notImplemented("{{.Name}}"){{end}}
}
{{end}}
`

func output() {
	// put in empty param names as needed
	for _, t := range types {
		if t.paramnames == nil {
			t.paramnames = make([]string, len(t.paramtypes))
		}
		for i, p := range t.paramtypes {
			cm := ""
			if i > 0 {
				cm = ", "
			}
			t.Param += fmt.Sprintf("%s%s %s", cm, t.paramnames[i], p)
			this := t.paramnames[i]
			if this == "_" {
				this = "nil"
			}
			t.Invoke += fmt.Sprintf("%s%s", cm, this)
		}
		if len(t.Results) > 1 {
			t.Result = "("
		}
		for i, r := range t.Results {
			cm := ""
			if i > 0 {
				cm = ", "
			}
			t.Result += fmt.Sprintf("%s%s", cm, r)
		}
		if len(t.Results) > 1 {
			t.Result += ")"
		}
	}

	fd, err := os.Create(*out)
	if err != nil {
		log.Fatal(err)
	}
	t, err := template.New("foo").Parse(tmpl)
	if err != nil {
		log.Fatal(err)
	}
	type par struct {
		Type  string
		Stuff []*Function
	}
	p := par{*typ, types}
	if false { // debugging the template
		t.Execute(os.Stderr, &p)
	}
	buf := bytes.NewBuffer(nil)
	err = t.Execute(buf, &p)
	if err != nil {
		log.Fatal(err)
	}
	ans, err := format.Source(bytes.Replace(buf.Bytes(), []byte("\\\n"), []byte{}, -1))
	if err != nil {
		log.Fatal(err)
	}
	fd.Write(ans)
}

func doUses() {
	fset := token.NewFileSet()
	pkgs, err := parser.ParseDir(fset, *use, nil, 0)
	if err != nil {
		log.Fatalf("%q:%v", *use, err)
	}
	pkg := pkgs["lsp"] // CHECK
	files := pkg.Files
	for fname, f := range files {
		for _, d := range f.Decls {
			fd, ok := d.(*ast.FuncDecl)
			if !ok {
				continue
			}
			nm := fd.Name.String()
			if ast.IsExported(nm) {
				// we're looking for things like didChange
				continue
			}
			if fx, ok := byname[nm]; ok {
				if fx.Found != "" {
					log.Fatalf("found %s in %s and %s", fx.Internal, fx.Found, fname)
				}
				fx.Found = fname
				// and the Paramnames
				ft := fd.Type
				for _, f := range ft.Params.List {
					nm := ""
					if len(f.Names) > 0 {
						nm = f.Names[0].String()
						if nm == "_" {
							nm = "_gen"
						}
					}
					fx.paramnames = append(fx.paramnames, nm)
				}
			}
		}
	}
	if false {
		for i, f := range types {
			log.Printf("%d %s %s", i, f.Internal, f.Found)
		}
	}
}

type Function struct {
	Name       string
	Internal   string // first letter lower case
	paramtypes []string
	paramnames []string
	Results    []string
	Param      string
	Result     string // do it in code, easier than in a template
	Invoke     string
	Found      string // file it was found in
}

var types []*Function
var byname = map[string]*Function{} // internal names

func doTypes() {
	fset := token.NewFileSet()
	f, err := parser.ParseFile(fset, *def, nil, 0)
	if err != nil {
		log.Fatal(err)
	}
	fd, err := os.Create("/tmp/ast")
	if err != nil {
		log.Fatal(err)
	}
	ast.Fprint(fd, fset, f, ast.NotNilFilter)
	ast.Inspect(f, inter)
	sort.Slice(types, func(i, j int) bool { return types[i].Name < types[j].Name })
	if false {
		for i, f := range types {
			log.Printf("%d %s(%v) %v", i, f.Name, f.paramtypes, f.Results)
		}
	}
}

func inter(n ast.Node) bool {
	x, ok := n.(*ast.TypeSpec)
	if !ok || x.Name.Name != *typ {
		return true
	}
	m := x.Type.(*ast.InterfaceType).Methods.List
	for _, fld := range m {
		fn := fld.Type.(*ast.FuncType)
		p := fn.Params.List
		r := fn.Results.List
		fx := &Function{
			Name: fld.Names[0].String(),
		}
		fx.Internal = strings.ToLower(fx.Name[:1]) + fx.Name[1:]
		for _, f := range p {
			fx.paramtypes = append(fx.paramtypes, whatis(f.Type))
		}
		for _, f := range r {
			fx.Results = append(fx.Results, whatis(f.Type))
		}
		types = append(types, fx)
		byname[fx.Internal] = fx
	}
	return false
}

func whatis(x ast.Expr) string {
	switch n := x.(type) {
	case *ast.SelectorExpr:
		return whatis(n.X) + "." + n.Sel.String()
	case *ast.StarExpr:
		return "*" + whatis(n.X)
	case *ast.Ident:
		if ast.IsExported(n.Name) {
			// these are from package protocol
			return "protocol." + n.Name
		}
		return n.Name
	case *ast.ArrayType:
		return "[]" + whatis(n.Elt)
	case *ast.InterfaceType:
		return "interface{}"
	default:
		log.Fatalf("Fatal %T", x)
		return fmt.Sprintf("%T", x)
	}
}
