// Copyright 2022 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 generate command generates Go declarations from VSCode's
// description of the Language Server Protocol.
//
// To run it, type 'go generate' in the parent (protocol) directory.
package main

// see https://github.com/golang/go/issues/61217 for discussion of an issue

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"go/format"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

const vscodeRepo = "https://github.com/microsoft/vscode-languageserver-node"

// lspGitRef names a branch or tag in vscodeRepo.
// It implicitly determines the protocol version of the LSP used by gopls.
// For example, tag release/protocol/3.17.3 of the repo defines protocol version 3.17.0.
// (Point releases are reflected in the git tag version even when they are cosmetic
// and don't change the protocol.)
var lspGitRef = "release/protocol/3.17.6-next.2"

var (
	repodir   = flag.String("d", "", "directory containing clone of "+vscodeRepo)
	outputdir = flag.String("o", ".", "output directory")
	// PJW: not for real code
	cmpdir      = flag.String("c", "", "directory of earlier code")
	doboth      = flag.String("b", "", "generate and compare")
	lineNumbers = flag.Bool("l", false, "add line numbers to generated output")
)

func main() {
	log.SetFlags(log.Lshortfile) // log file name and line number, not time
	flag.Parse()

	processinline()
}

func processinline() {
	// A local repository may be specified during debugging.
	// The default behavior is to download the canonical version.
	if *repodir == "" {
		tmpdir, err := os.MkdirTemp("", "")
		if err != nil {
			log.Fatal(err)
		}
		defer os.RemoveAll(tmpdir) // ignore error

		// Clone the repository.
		cmd := exec.Command("git", "clone", "--quiet", "--depth=1", "-c", "advice.detachedHead=false", vscodeRepo, "--branch="+lspGitRef, "--single-branch", tmpdir)
		cmd.Stdout = os.Stderr
		cmd.Stderr = os.Stderr
		if err := cmd.Run(); err != nil {
			log.Fatal(err)
		}

		*repodir = tmpdir
	} else {
		lspGitRef = fmt.Sprintf("(not git, local dir %s)", *repodir)
	}

	model := parse(filepath.Join(*repodir, "protocol/metaModel.json"))

	findTypeNames(model)
	generateOutput(model)

	fileHdr = fileHeader(model)

	// write the files
	writeclient()
	writeserver()
	writeprotocol()
	writejsons()

	checkTables()
}

// common file header for output files
var fileHdr string

func writeclient() {
	out := new(bytes.Buffer)
	fmt.Fprintln(out, fileHdr)
	out.WriteString(
		`import (
	"context"

	"golang.org/x/tools/internal/jsonrpc2"
)
`)
	out.WriteString("type Client interface {\n")
	for _, k := range cdecls.keys() {
		out.WriteString(cdecls[k])
	}
	out.WriteString("}\n\n")
	out.WriteString(`func clientDispatch(ctx context.Context, client Client, reply jsonrpc2.Replier, r jsonrpc2.Request) (bool, error) {
	defer recoverHandlerPanic(r.Method())
	switch r.Method() {
`)
	for _, k := range ccases.keys() {
		out.WriteString(ccases[k])
	}
	out.WriteString(("\tdefault:\n\t\treturn false, nil\n\t}\n}\n\n"))
	for _, k := range cfuncs.keys() {
		out.WriteString(cfuncs[k])
	}

	x, err := format.Source(out.Bytes())
	if err != nil {
		os.WriteFile("/tmp/a.go", out.Bytes(), 0644)
		log.Fatalf("tsclient.go: %v", err)
	}

	if err := os.WriteFile(filepath.Join(*outputdir, "tsclient.go"), x, 0644); err != nil {
		log.Fatalf("%v writing tsclient.go", err)
	}
}

func writeserver() {
	out := new(bytes.Buffer)
	fmt.Fprintln(out, fileHdr)
	out.WriteString(
		`import (
	"context"

	"golang.org/x/tools/internal/jsonrpc2"
)
`)
	out.WriteString("type Server interface {\n")
	for _, k := range sdecls.keys() {
		out.WriteString(sdecls[k])
	}
	out.WriteString(`
}

func serverDispatch(ctx context.Context, server Server, reply jsonrpc2.Replier, r jsonrpc2.Request) (bool, error) {
	defer recoverHandlerPanic(r.Method())
	switch r.Method() {
`)
	for _, k := range scases.keys() {
		out.WriteString(scases[k])
	}
	out.WriteString(("\tdefault:\n\t\treturn false, nil\n\t}\n}\n\n"))
	for _, k := range sfuncs.keys() {
		out.WriteString(sfuncs[k])
	}
	x, err := format.Source(out.Bytes())
	if err != nil {
		os.WriteFile("/tmp/a.go", out.Bytes(), 0644)
		log.Fatalf("tsserver.go: %v", err)
	}

	if err := os.WriteFile(filepath.Join(*outputdir, "tsserver.go"), x, 0644); err != nil {
		log.Fatalf("%v writing tsserver.go", err)
	}
}

func writeprotocol() {
	out := new(bytes.Buffer)
	fmt.Fprintln(out, fileHdr)
	out.WriteString("import \"encoding/json\"\n\n")

	// The followiing are unneeded, but make the new code a superset of the old
	hack := func(newer, existing string) {
		if _, ok := types[existing]; !ok {
			log.Fatalf("types[%q] not found", existing)
		}
		types[newer] = strings.Replace(types[existing], existing, newer, 1)
	}
	hack("ConfigurationParams", "ParamConfiguration")
	hack("InitializeParams", "ParamInitialize")
	hack("PreviousResultId", "PreviousResultID")
	hack("WorkspaceFoldersServerCapabilities", "WorkspaceFolders5Gn")
	hack("_InitializeParams", "XInitializeParams")

	for _, k := range types.keys() {
		if k == "WatchKind" {
			types[k] = "type WatchKind = uint32" // strict gopls compatibility needs the '='
		}
		out.WriteString(types[k])
	}

	out.WriteString("\nconst (\n")
	for _, k := range consts.keys() {
		out.WriteString(consts[k])
	}
	out.WriteString(")\n\n")
	x, err := format.Source(out.Bytes())
	if err != nil {
		os.WriteFile("/tmp/a.go", out.Bytes(), 0644)
		log.Fatalf("tsprotocol.go: %v", err)
	}
	if err := os.WriteFile(filepath.Join(*outputdir, "tsprotocol.go"), x, 0644); err != nil {
		log.Fatalf("%v writing tsprotocol.go", err)
	}
}

func writejsons() {
	out := new(bytes.Buffer)
	fmt.Fprintln(out, fileHdr)
	out.WriteString("import \"encoding/json\"\n\n")
	out.WriteString("import \"fmt\"\n")

	out.WriteString(`
// UnmarshalError indicates that a JSON value did not conform to
// one of the expected cases of an LSP union type.
type UnmarshalError struct {
	msg string
}

func (e UnmarshalError) Error() string {
	return e.msg
}
`)

	for _, k := range jsons.keys() {
		out.WriteString(jsons[k])
	}
	x, err := format.Source(out.Bytes())
	if err != nil {
		os.WriteFile("/tmp/a.go", out.Bytes(), 0644)
		log.Fatalf("tsjson.go: %v", err)
	}
	if err := os.WriteFile(filepath.Join(*outputdir, "tsjson.go"), x, 0644); err != nil {
		log.Fatalf("%v writing tsjson.go", err)
	}
}

// create the common file header for the output files
func fileHeader(model Model) string {
	fname := filepath.Join(*repodir, ".git", "HEAD")
	buf, err := os.ReadFile(fname)
	if err != nil {
		log.Fatal(err)
	}
	buf = bytes.TrimSpace(buf)
	var githash string
	if len(buf) == 40 {
		githash = string(buf[:40])
	} else if bytes.HasPrefix(buf, []byte("ref: ")) {
		fname = filepath.Join(*repodir, ".git", string(buf[5:]))
		buf, err = os.ReadFile(fname)
		if err != nil {
			log.Fatal(err)
		}
		githash = string(buf[:40])
	} else {
		log.Fatalf("githash cannot be recovered from %s", fname)
	}

	format := `// Copyright 2023 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.

// Code generated for LSP. DO NOT EDIT.

package protocol

// Code generated from %[1]s at ref %[2]s (hash %[3]s).
// %[4]s/blob/%[2]s/%[1]s
// LSP metaData.version = %[5]s.

`
	return fmt.Sprintf(format,
		"protocol/metaModel.json", // 1
		lspGitRef,                 // 2
		githash,                   // 3
		vscodeRepo,                // 4
		model.Version.Version)     // 5
}

func parse(fname string) Model {
	buf, err := os.ReadFile(fname)
	if err != nil {
		log.Fatal(err)
	}
	buf = addLineNumbers(buf)
	var model Model
	if err := json.Unmarshal(buf, &model); err != nil {
		log.Fatal(err)
	}
	return model
}

// Type.Value has to be treated specially for literals and maps
func (t *Type) UnmarshalJSON(data []byte) error {
	// First unmarshal only the unambiguous fields.
	var x struct {
		Kind    string  `json:"kind"`
		Items   []*Type `json:"items"`
		Element *Type   `json:"element"`
		Name    string  `json:"name"`
		Key     *Type   `json:"key"`
		Value   any     `json:"value"`
		Line    int     `json:"line"`
	}
	if err := json.Unmarshal(data, &x); err != nil {
		return err
	}
	*t = Type{
		Kind:    x.Kind,
		Items:   x.Items,
		Element: x.Element,
		Name:    x.Name,
		Value:   x.Value,
		Line:    x.Line,
	}

	// Then unmarshal the 'value' field based on the kind.
	// This depends on Unmarshal ignoring fields it doesn't know about.
	switch x.Kind {
	case "map":
		var x struct {
			Key   *Type `json:"key"`
			Value *Type `json:"value"`
		}
		if err := json.Unmarshal(data, &x); err != nil {
			return fmt.Errorf("Type.kind=map: %v", err)
		}
		t.Key = x.Key
		t.Value = x.Value

	case "literal":
		var z struct {
			Value ParseLiteral `json:"value"`
		}

		if err := json.Unmarshal(data, &z); err != nil {
			return fmt.Errorf("Type.kind=literal: %v", err)
		}
		t.Value = z.Value

	case "base", "reference", "array", "and", "or", "tuple",
		"stringLiteral":
		// no-op. never seen integerLiteral or booleanLiteral.

	default:
		return fmt.Errorf("cannot decode Type.kind %q: %s", x.Kind, data)
	}
	return nil
}

// which table entries were not used
func checkTables() {
	for k := range disambiguate {
		if !usedDisambiguate[k] {
			log.Printf("disambiguate[%v] unused", k)
		}
	}
	for k := range renameProp {
		if !usedRenameProp[k] {
			log.Printf("renameProp {%q, %q} unused", k[0], k[1])
		}
	}
	for k := range goplsStar {
		if !usedGoplsStar[k] {
			log.Printf("goplsStar {%q, %q} unused", k[0], k[1])
		}
	}
	for k := range goplsType {
		if !usedGoplsType[k] {
			log.Printf("unused goplsType[%q]->%s", k, goplsType[k])
		}
	}
}
