// 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 generate is used to generate command bindings from the gopls command
// interface.
package generate

import (
	"bytes"
	"fmt"
	"go/types"
	"text/template"

	"golang.org/x/tools/internal/imports"
	"golang.org/x/tools/internal/lsp/command/commandmeta"
)

const src = `// 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.

// Don't include this file during code generation, or it will break the build
// if existing interface methods have been modified.
// +build !generate

package command

// Code generated by generate.go. DO NOT EDIT.

import (
	{{range $k, $v := .Imports -}}
	"{{$k}}"
	{{end}}
)

const (
{{- range .Commands}}
	{{.MethodName}} Command = "{{.Name}}"
{{- end}}
)

var Commands = []Command {
{{- range .Commands}}
	{{.MethodName}},
{{- end}}
}

func Dispatch(ctx context.Context, params *protocol.ExecuteCommandParams, s Interface) (interface{}, error) {
	switch params.Command {
	{{- range .Commands}}
	case "{{.ID}}":
		{{- if .Args -}}
			{{- range $i, $v := .Args}}
		var a{{$i}} {{typeString $v.Type}}
			{{- end}}
		if err := UnmarshalArgs(params.Arguments{{range $i, $v := .Args}}, &a{{$i}}{{end}}); err != nil {
			return nil, err
		}
		{{end -}}
		{{- if .Result -}}res, {{end}}err := s.{{.MethodName}}(ctx{{range $i, $v := .Args}}, a{{$i}}{{end}})
		return {{if .Result}}res{{else}}nil{{end}}, err
	{{- end}}
	}
	return nil, fmt.Errorf("unsupported command %q", params.Command)
}
{{- range .Commands}}

func New{{.MethodName}}Command(title string, {{range $i, $v := .Args}}{{if $i}}, {{end}}a{{$i}} {{typeString $v.Type}}{{end}}) (protocol.Command, error) {
	args, err := MarshalArgs({{range $i, $v := .Args}}{{if $i}}, {{end}}a{{$i}}{{end}})
	if err != nil {
		return protocol.Command{}, err
	}
	return protocol.Command{
		Title: title,
		Command: "{{.ID}}",
		Arguments: args,
	}, nil
}
{{end}}
`

type data struct {
	Imports  map[string]bool
	Commands []*commandmeta.Command
}

func Generate() ([]byte, error) {
	pkg, cmds, err := commandmeta.Load()
	if err != nil {
		return nil, fmt.Errorf("loading command data: %v", err)
	}
	qf := func(p *types.Package) string {
		if p == pkg.Types {
			return ""
		}
		return p.Name()
	}
	tmpl, err := template.New("").Funcs(template.FuncMap{
		"typeString": func(t types.Type) string {
			return types.TypeString(t, qf)
		},
	}).Parse(src)
	if err != nil {
		return nil, err
	}
	d := data{
		Commands: cmds,
		Imports: map[string]bool{
			"context": true,
			"fmt":     true,
			"golang.org/x/tools/internal/lsp/protocol": true,
		},
	}
	const thispkg = "golang.org/x/tools/internal/lsp/command"
	for _, c := range d.Commands {
		for _, arg := range c.Args {
			pth := pkgPath(arg.Type)
			if pth != "" && pth != thispkg {
				d.Imports[pth] = true
			}
		}
		pth := pkgPath(c.Result)
		if pth != "" && pth != thispkg {
			d.Imports[pth] = true
		}
	}

	var buf bytes.Buffer
	if err := tmpl.Execute(&buf, d); err != nil {
		return nil, fmt.Errorf("executing: %v", err)
	}

	opts := &imports.Options{
		AllErrors:  true,
		FormatOnly: true,
		Comments:   true,
	}
	content, err := imports.Process("", buf.Bytes(), opts)
	if err != nil {
		return nil, fmt.Errorf("goimports: %v", err)
	}
	return content, nil
}

func pkgPath(t types.Type) string {
	if n, ok := t.(*types.Named); ok {
		if pkg := n.Obj().Pkg(); pkg != nil {
			return pkg.Path()
		}
	}
	return ""
}
