// Copyright 2020 The Go Authors. All rights reserved.
// Licensed under the MIT License.
// See LICENSE in the project root for license information.

// Command generate is used to update package.json based on
// the gopls's API and generate documentation from it.
//
// To update documentation based on the current package.json:
//
//	go run tools/generate.go
//
// To update package.json and generate documentation.
//
//	go run tools/generate.go -gopls
package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"sort"
	"strings"

	"github.com/golang/vscode-go/extension/tools/goplssetting"
)

var (
	writeFlag                    = flag.Bool("w", true, "Write new file contents to disk.")
	updateGoplsSettingsFlag      = flag.Bool("gopls", false, "Update gopls settings in package.json. This is disabled by default because 'jq' tool is needed for generation.")
	updateLatestToolVersionsFlag = flag.Bool("tools", false, "Update the latest versions of tools in src/src/goToolsInformation.ts. This is disabled by default because the latest versions may change frequently and should not block a release.")

	debugFlag = flag.Bool("debug", false, "If true, enable extra logging and skip deletion of intermediate files.")
)

func checkAndWrite(filename string, oldContent, newContent []byte) {
	// Return early if the contents are unchanged.
	if bytes.Equal(oldContent, newContent) {
		return
	}

	// Either write out new contents or report an error (if in CI).
	if *writeFlag {
		if err := ioutil.WriteFile(filename, newContent, 0644); err != nil {
			log.Fatal(err)
		}
		fmt.Printf("updated %s\n", filename)
	} else {
		base := filepath.Join("..", "docs", filepath.Base(filename))
		fmt.Printf(`%s have changed in the package.json, but documentation in %s was not updated.
To update the settings, run "go run tools/generate.go -w".
`, strings.TrimSuffix(base, ".md"), base)
		os.Exit(1) // causes CI to break.
	}
}

type PackageJSON struct {
	Contributes struct {
		Commands      []Command `json:"commands,omitempty"`
		Configuration struct {
			Properties map[string]*Property `json:"properties,omitempty"`
		} `json:"configuration"`
		Debuggers []Debugger `json:"debuggers,omitempty"`
	} `json:"contributes"`
}

type Command struct {
	Command     string `json:"command,omitempty"`
	Title       string `json:"title,omitempty"`
	Description string `json:"description,omitempty"`
}

type Property struct {
	name string `json:"name,omitempty"` // Set by us.

	// Below are defined in package.json
	Properties                 map[string]*Property `json:"properties,omitempty"`
	AnyOf                      []Property           `json:"anyOf,omitempty"`
	Default                    any                  `json:"default,omitempty"`
	MarkdownDescription        string               `json:"markdownDescription,omitempty"`
	Description                string               `json:"description,omitempty"`
	MarkdownDeprecationMessage string               `json:"markdownDeprecationMessage,omitempty"`
	DeprecationMessage         string               `json:"deprecationMessage,omitempty"`
	Type                       any                  `json:"type,omitempty"`
	Enum                       []any                `json:"enum,omitempty"`
	EnumDescriptions           []string             `json:"enumDescriptions,omitempty"`
	MarkdownEnumDescriptions   []string             `json:"markdownEnumDescriptions,omitempty"`
	Items                      *Property            `json:"items,omitempty"`
}

type Debugger struct {
	Type                    string `json:"type,omitempty"`
	Label                   string `json:"label,omitempty"`
	ConfigurationAttributes struct {
		Launch Configuration
		Attach Configuration
	} `json:"configurationAttributes"`
}

type Configuration struct {
	Properties map[string]*Property `json:"properties,omitempty"`
}

type moduleVersion struct {
	Path     string   `json:",omitempty"`
	Version  string   `json:",omitempty"`
	Time     string   `json:",omitempty"`
	Versions []string `json:",omitempty"`
}

func main() {
	flag.Parse()

	// Assume this is running from the vscode-go directory.
	dir, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}

	packageJSONFile := filepath.Join(dir, "package.json")

	// Find the package.json file.
	data, err := ioutil.ReadFile(packageJSONFile)
	if err != nil {
		log.Fatal(err)
	}

	if *updateGoplsSettingsFlag {
		newData, err := updateGoplsSettings(data, packageJSONFile, *debugFlag)
		if err != nil {
			log.Fatal(err)
		}
		data = newData
	}

	pkgJSON := &PackageJSON{}
	if err := json.Unmarshal(data, pkgJSON); err != nil {
		log.Fatal(err)
	}

	rewrite := func(filename string, toAdd []byte) {
		oldContent, err := ioutil.ReadFile(filename)
		if err != nil {
			log.Fatal(err)
		}
		gen := []byte(`<!-- Everything below this line is generated. DO NOT EDIT. -->`)
		split := bytes.Split(oldContent, gen)
		if len(split) == 1 {
			log.Fatalf("expected to find %q in %s, not found", gen, filename)
		}
		var s []byte
		if strings.HasSuffix(filename, ".ts") {
			s = bytes.Join([][]byte{
				split[0],
				gen,
				[]byte("\n\n"),
				toAdd,
			}, []byte{})
		} else {
			s = bytes.Join([][]byte{
				bytes.TrimSpace(split[0]),
				gen,
				toAdd,
			}, []byte("\n\n"))
		}
		newContent := append(s, '\n')
		checkAndWrite(filename, oldContent, newContent)
	}

	b := &bytes.Buffer{}
	for i, c := range pkgJSON.Contributes.Commands {
		fmt.Fprintf(b, "### `%s`\n\n%s", c.Title, c.Description)
		if i != len(pkgJSON.Contributes.Commands)-1 {
			b.WriteString("\n\n")
		}
	}
	rewrite(filepath.Join(dir, "..", "docs", "commands.md"), b.Bytes())

	// Clear so that we can rewrite settings.md.
	b.Reset()

	var properties []*Property
	var goplsProperty *Property
	for name, p := range pkgJSON.Contributes.Configuration.Properties {
		p.name = name
		if name == "gopls" {
			goplsProperty = p
		}
		properties = append(properties, p)
	}

	sort.Slice(properties, func(i, j int) bool {
		return properties[i].name < properties[j].name
	})

	for _, p := range properties {
		if p.name == "gopls" {
			desc := "Customize `gopls` behavior by specifying the gopls' settings in this section. " +
				"For example, \n```\n\"gopls\" : {\n\t\"build.directoryFilters\": [\"-node_modules\"]\n\t...\n}\n```\n" +
				"This section is directly read by `gopls`. See the [`gopls` section](#settings-for-gopls) section " +
				"for the full list of `gopls` settings."
			fmt.Fprintf(b, "### `%s`\n\n%s", p.name, desc)
			b.WriteString("\n\n")
			continue
		}

		writeProperty(b, "###", p)
		b.WriteString("\n")
	}

	// Write gopls section.
	b.WriteString("## Settings for `gopls`\n\n")
	writeGoplsSettingsSection(b, goplsProperty)

	rewrite(filepath.Join(dir, "..", "docs", "settings.md"), b.Bytes())

	b.Reset()
	generateDebugConfigTable(b, pkgJSON)
	rewriteDebugDoc(filepath.Join(dir, "..", "docs", "debugging.md"), b.Bytes())

	// Only update the latest tool versions if the flag is set.
	if !*updateLatestToolVersionsFlag {
		return
	}

	// Clear so that we can rewrite src/goToolsInformation.ts.
	b.Reset()

	// Check for the latest gopls version.
	versions, err := listAllModuleVersions("golang.org/x/tools/gopls")
	if err != nil {
		log.Fatalf("failed to list all module version: %v", err)
	}
	latestIndex := len(versions.Versions) - 1
	// We need to find the last version that was not a pre-release.
	var latest string
	for ; latestIndex >= 0; latestIndex-- {
		latest = versions.Versions[latestIndex]
		if !strings.Contains(latest, "pre") {
			break
		}
	}

	goplsVersion, err := listModuleVersion(fmt.Sprintf("golang.org/x/tools/gopls@%s", latest))
	if err != nil {
		log.Fatalf("failed to list gopls latest version: %v", err)
	}

	allToolsFile := filepath.Join(dir, "tools", "allTools.ts.in")

	// Find the package.json file.
	data, err = ioutil.ReadFile(allToolsFile)
	if err != nil {
		log.Fatal(err)
	}

	// TODO(suzmue): change input to json and avoid magic string printing.
	toolsString := fmt.Sprintf(string(data), goplsVersion.Version, goplsVersion.Time[:len("YYYY-MM-DD")])

	// Write tools section.
	b.WriteString(toolsString)
	rewrite(filepath.Join(dir, "src", "goToolsInformation.ts"), b.Bytes())
}

func listModuleVersion(path string) (moduleVersion, error) {
	cmd := exec.Command("go", "list", "-m", "-json", path)
	cmd.Stderr = os.Stderr
	output, err := cmd.Output()
	if err != nil {
		return moduleVersion{}, err
	}
	var version moduleVersion
	err = json.Unmarshal(output, &version)
	if err != nil {
		return moduleVersion{}, err
	}
	return version, nil
}

func listAllModuleVersions(path string) (moduleVersion, error) {
	cmd := exec.Command("go", "list", "-m", "-json", "-versions", path)
	cmd.Stderr = os.Stderr
	output, err := cmd.Output()
	if err != nil {
		return moduleVersion{}, err
	}
	var version moduleVersion
	err = json.Unmarshal(output, &version)
	if err != nil {
		return moduleVersion{}, err
	}
	return version, nil
}

func writeProperty(b *bytes.Buffer, heading string, p *Property) {
	desc := p.Description
	if p.MarkdownDescription != "" {
		desc = p.MarkdownDescription
	}
	deprecation := p.DeprecationMessage
	if p.MarkdownDeprecationMessage != "" {
		deprecation = p.MarkdownDeprecationMessage
	}

	name := p.name
	if deprecation != "" {
		name += " (deprecated)"
		desc = deprecation + "\n" + desc
	}

	fmt.Fprintf(b, "%s `%s`\n\n%s", heading, name, desc)

	if enums := enumDescriptionsSnippet(p); enums != "" {
		fmt.Fprintf(b, "<br/>\n%s", enums)
	}

	if p.Type == "object" {
		writeSettingsObjectProperties(b, p.Properties)
	}

	if defaults := defaultDescriptionSnippet(p); defaults != "" {
		b.WriteString("\n\n")
		if p.Type == "object" {
			fmt.Fprintf(b, "Default:\n```\n%v\n```", defaults)
		} else {
			fmt.Fprintf(b, "Default: `%v`", defaults)
		}
	}
}

func defaultDescriptionSnippet(p *Property) string {
	if p.Default == nil {
		return ""
	}
	b := &bytes.Buffer{}
	switch p.Type {
	case "object":
		x, ok := p.Default.(map[string]any)
		if !ok {
			panic(fmt.Sprintf("unexpected type of object: %v", *p))
		} else if len(x) > 0 {
			// do nothing if it is nil
			writeMapObject(b, "", x)
		}
	case "string":
		fmt.Fprintf(b, "%q", p.Default)
	case "boolean", "number":
		fmt.Fprintf(b, "%v", p.Default)
	case "array":
		x, ok := p.Default.([]any)
		if !ok {
			panic(fmt.Sprintf("unexpected type for array: %v", *p))
		} else if len(x) > 0 {
			fmt.Fprintf(b, "[")
			for i, v := range x {
				if i > 0 {
					fmt.Fprintf(b, ", ")
				}
				fmt.Fprintf(b, "%q", v)
			}
			fmt.Fprintf(b, "]")
		}
	default:
		fmt.Fprintf(b, "%v", p.Default)
	}
	return b.String()
}

func writeMapObject(b *bytes.Buffer, indent string, obj map[string]any) {
	keys := []string{}
	for k := range obj {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	fmt.Fprintf(b, "%v{\n", indent)
	for _, k := range keys {
		fmt.Fprintf(b, "%v%q :\t", indent+"\t", k)

		v := obj[k]
		switch v := v.(type) {
		case string:
			fmt.Fprintf(b, "%q", v)
		case map[string]any:
			writeMapObject(b, indent+"\t", v)
		default:
			fmt.Fprintf(b, "%v", v)
		}
		fmt.Fprint(b, ",\n")
	}
	fmt.Fprintf(b, "%v}", indent)
}

func writeGoplsSettingsSection(b *bytes.Buffer, goplsProperty *Property) {
	desc := goplsProperty.MarkdownDescription
	b.WriteString(desc)
	b.WriteString("\n\n")

	properties := goplsProperty.Properties
	var names []string
	for name := range properties {
		names = append(names, name)
	}
	sort.Strings(names)

	for _, name := range names {
		p := properties[name]
		p.name = name
		writeProperty(b, "###", p)
		b.WriteString("\n")
	}
}

func writeSettingsObjectProperties(b *bytes.Buffer, properties map[string]*Property) {
	if len(properties) == 0 {
		return
	}

	var names []string
	for name := range properties {
		names = append(names, name)
	}
	sort.Strings(names)
	b.WriteString("\n")
	b.WriteString("| Properties | Description |\n")
	b.WriteString("| --- | --- |\n")
	ending := "\n"
	for i, name := range names {
		if i == len(names)-1 {
			ending = ""
		}
		p := properties[name]
		p.name = name

		desc := p.Description
		if p.MarkdownDescription != "" {
			desc = p.MarkdownDescription
		}
		deprecation := p.DeprecationMessage
		if p.MarkdownDeprecationMessage != "" {
			deprecation = p.MarkdownDeprecationMessage
		}
		if deprecation != "" {
			name += " (deprecated)"
			desc = deprecation + "\n" + desc
		}

		if enum := enumDescriptionsSnippet(p); enum != "" {
			desc += "\n\n" + enum
		}

		if defaults := defaultDescriptionSnippet(p); defaults != "" {
			desc += "\n\n"
			if p.Type == "object" {
				desc += fmt.Sprintf("Default:\n```\n%v\n```", defaults)
			} else {
				desc += fmt.Sprintf("Default: `%v`", defaults)
			}
		}
		desc = gocommentToMarkdown(desc)
		fmt.Fprintf(b, "| `%s` | %s |%v", name, desc, ending)
	}
}

// enumDescriptionsSnippet returns the snippet for the allowed values.
func enumDescriptionsSnippet(p *Property) string {
	b := &bytes.Buffer{}
	if len(p.Enum) == 0 {
		return ""
	}
	desc := p.EnumDescriptions
	if len(p.MarkdownEnumDescriptions) != 0 {
		desc = p.MarkdownEnumDescriptions
	}

	hasDesc := false
	for _, d := range desc {
		if d != "" {
			hasDesc = true
			break
		}
	}
	b.WriteString("Allowed Options:")

	if hasDesc && len(desc) == len(p.Enum) {
		b.WriteString("\n\n")
		for i, e := range p.Enum {
			enumName := fmt.Sprintf("`%v`", e)
			if d := desc[i]; d == "" {
				fmt.Fprintf(b, "* %v", enumName)
			} else {
				enumDesc := strings.TrimRight(strings.ReplaceAll(d, "\n\n", "<br/>"), "\n")
				if strings.HasPrefix(d, enumName+":") {
					// gopls's enum descriptions are sometimes already formatted
					// like `name: description` format. Remove the duplicate prefix.
					fmt.Fprintf(b, "* %v", enumDesc)
				} else {
					fmt.Fprintf(b, "* %v: %v", enumName, enumDesc)
				}
			}
			b.WriteString("\n")
		}
	} else {
		for i, e := range p.Enum {
			fmt.Fprintf(b, " `%v`", e)
			if i < len(p.Enum)-1 {
				b.WriteString(",")
			}
		}
	}
	return b.String()
}

// gocommentToMarkdown converts the description string generated based on go comments
// to more markdown-friendly style.
//   - treat indented lines as pre-formatted blocks (e.g. code snippets) like in go doc
//   - replace new lines with <br/>'s, so the new lines mess up formatting when embedded in tables
//   - preserve new lines inside preformatted sections, but replace them with <br/>'s
//   - skip unneeded new lines
func gocommentToMarkdown(s string) string {
	lines := strings.Split(s, "\n")
	inPre := false
	b := &bytes.Buffer{}
	for i, l := range lines {
		if strings.HasPrefix(l, "\t") { // indented
			if !inPre { // beginning of the block
				inPre = true
				b.WriteString("<pre>")
			} else { // preserve new lines in pre-formatted block
				b.WriteString("<br/>")
			}
			l = l[1:] // remove one leading \t, in favor of <pre></pre> formatting.
		} else { // not indented
			if inPre {
				inPre = false
				b.WriteString("</pre>")
			}
		}
		if l == "" && i != len(lines)-1 {
			b.WriteString("<br/>") // add a new line.
		} else {
			b.WriteString(l) // just print l, no new line.
		}
		if i != len(lines)-1 {
			if !inPre {
				b.WriteString(" ")
			}
		}
	}
	return b.String()
}

func updateGoplsSettings(oldData []byte, packageJSONFile string, debug bool) (newData []byte, _ error) {
	newData, err := goplssetting.Generate(packageJSONFile, debug)
	if err != nil { // failed to compute up-to-date gopls settings.
		return nil, err
	}

	if bytes.Equal(oldData, newData) {
		return oldData, nil
	}

	if !*writeFlag {
		fmt.Println(`gopls settings section in package.json needs update. To update the settings, run "go run tools/generate.go -w -gopls".`)
		os.Exit(1) // causes CI to break.
	}

	if err := ioutil.WriteFile(packageJSONFile, newData, 0644); err != nil {
		return nil, err
	}
	return newData, nil
}

func rewriteDebugDoc(filename string, toAdd []byte) {
	oldContent, err := ioutil.ReadFile(filename)
	if err != nil {
		log.Fatal(err)
	}
	startSep := []byte(`<!-- SETTINGS BEGIN -->`)
	endSep := []byte(`<!-- SETTINGS END -->`)
	startIdx := bytes.Index(oldContent, startSep)
	endIdx := bytes.Index(oldContent, endSep)
	if startIdx <= 0 || endIdx <= startIdx {
		log.Fatalf("Missing valid SETTINGS BEGIN/END markers in %v", filename)
	}
	part1 := oldContent[:startIdx+len(startSep)+1]
	part3 := oldContent[endIdx:]

	newContent := bytes.Join([][]byte{
		part1,
		toAdd,
		part3,
	}, []byte{})
	checkAndWrite(filename, oldContent, newContent)
}

func generateDebugConfigTable(w io.Writer, pkgJSON *PackageJSON) {
	for _, d := range pkgJSON.Contributes.Debuggers {
		table := map[string]bool{}

		for k := range d.ConfigurationAttributes.Attach.Properties {
			table[k] = true
		}
		for k := range d.ConfigurationAttributes.Launch.Properties {
			table[k] = true
		}

		keys := make([]string, 0, len(table))
		for k := range table {
			keys = append(keys, k)
		}
		sort.Strings(keys)

		fmt.Fprintln(w, "| Property | Launch | Attach |")
		fmt.Fprintln(w, "| --- | --- | --- |")

		for _, k := range keys {
			launch := describeDebugProperty(d.ConfigurationAttributes.Launch.Properties[k])
			attach := describeDebugProperty(d.ConfigurationAttributes.Attach.Properties[k])

			if launch != "" && attach != "" {
				if launch != attach {
					fmt.Fprintf(w, "| `%v` | %v | %v |\n", k, launch, attach)
				} else {
					fmt.Fprintf(w, "| `%v` | %v | <center>_same as Launch_</center>|\n", k, launch)
				}
			} else if launch != "" {
				fmt.Fprintf(w, "| `%v` | %v | <center>_n/a_</center> |\n", k, launch)
			} else if attach != "" {
				fmt.Fprintf(w, "| `%v` | <center>_n/a_</center> | %v |\n", k, attach)
			}
		}
	}
}

func describeDebugProperty(p *Property) string {
	if p == nil {
		return ""
	}
	b := &bytes.Buffer{}

	desc := p.Description
	if p.MarkdownDescription != "" {
		desc = p.MarkdownDescription
	}
	if strings.Contains(desc, "Not applicable when using `dlv-dap` mode.") {
		return ""
	}

	deprecation := p.DeprecationMessage
	if p.MarkdownDeprecationMessage != "" {
		deprecation = p.MarkdownDeprecationMessage
	}

	if deprecation != "" {
		fmt.Fprintf(b, "(Deprecated) *%v*<br/>", deprecation)
	}
	fmt.Fprintf(b, "%v<br/>", desc)

	if len(p.AnyOf) > 0 {
		for i, a := range p.AnyOf {
			fmt.Fprintf(b, "<p><b>Option %d:</b> %v<br/>", i+1, describeDebugProperty(&a))
		}
	}

	if len(p.Enum) > 0 {
		var enums []string
		for _, i := range p.Enum {
			enums = append(enums, fmt.Sprintf("`%#v`", i))
		}
		fmt.Fprintf(b, "<p>Allowed Values: %v<br/>", strings.Join(enums, ", "))
	}

	if p.Type == "object" && len(p.Properties) > 0 {

		var keys []string
		for k := range p.Properties {
			keys = append(keys, k)
		}
		sort.Strings(keys)
		fmt.Fprintf(b, "<ul>")

		for _, k := range keys {
			v := p.Properties[k]
			fmt.Fprintf(b, "<li>`%q`: %v</li>", k, describeDebugProperty(v))
		}
		fmt.Fprintf(b, "</ul>")
	}

	if p.Type == "array" && p.Items != nil && p.Items.Type == "object" {
		fmt.Fprintf(b, "<p>%v<br/>", describeDebugProperty(p.Items))
	}

	// Default
	if d := defaultDescriptionSnippet(p); d != "" {
		fmt.Fprintf(b, "(Default: `%v`)<br/>", d)
	}
	return b.String()
}
