// 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/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,omitempty"`
		Debuggers []Debugger `json:"debuggers,omitempty"`
	} `json:"contributes,omitempty"`
}

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                    interface{}          `json:"default,omitempty"`
	MarkdownDescription        string               `json:"markdownDescription,omitempty"`
	Description                string               `json:"description,omitempty"`
	MarkdownDeprecationMessage string               `json:"markdownDeprecationMessage,omitempty"`
	DeprecationMessage         string               `json:"deprecationMessage,omitempty"`
	Type                       interface{}          `json:"type,omitempty"`
	Enum                       []interface{}        `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,omitempty"`
}

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", "dlv-dap.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 latest dlv-dap version.
	dlvVersion, err := listModuleVersion("github.com/go-delve/delve@master")
	if err != nil {
		log.Fatal(err)
	}

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

	goplsVersion, err := listModuleVersion(fmt.Sprintf("golang.org/x/tools/gopls@%s", latest))
	if err != nil {
		log.Fatal(err)
	}
	goplsVersionPre, err := listModuleVersion(fmt.Sprintf("golang.org/x/tools/gopls@%s", latestPre))
	if err != nil {
		log.Fatal(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")], goplsVersionPre.Version, goplsVersionPre.Time[:len("YYYY-MM-DD")], dlvVersion.Version, dlvVersion.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) {
	output, err := exec.Command("go", "list", "-m", "-json", path).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) {
	output, err := exec.Command("go", "list", "-m", "-json", "-versions", path).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]interface{})
		// do nothing if it is nil
		if ok && len(x) > 0 {
			writeMapObject(b, "", x)
		}
	case "string":
		fmt.Fprintf(b, "%q", p.Default)
	case "boolean", "number":
		fmt.Fprintf(b, "%v", p.Default)
	case "array":
		if x, ok := p.Default.([]interface{}); ok && len(x) > 0 {
			fmt.Fprintf(b, "%v", p.Default)
		}
	default:
		fmt.Fprintf(b, "%v", p.Default)
	}
	return b.String()
}

func writeMapObject(b *bytes.Buffer, indent string, obj map[string]interface{}) {
	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]interface{}:
			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 {
			fmt.Fprintf(b, "* `%v`", e)
			if d := desc[i]; d != "" {
				fmt.Fprintf(b, ": %v", strings.TrimRight(strings.ReplaceAll(d, "\n\n", "<br/>"), "\n"))
			}
			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 p == nil || 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()
}
