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

// This command updates the gopls.* configurations in vscode-go package.json.
//
//   Usage: from the project root directory,
//      $ go run tools/goplssetting -in ./package.json -out ./package.json
package main

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

var (
	inPkgJSON  = flag.String("in", "", "input package.json location")
	outPkgJSON = flag.String("out", "", "output package.json location. If empty, output to the standard output.")

	work = flag.Bool("w", false, "if true, do not delete intermediate files")
)

func main() {
	flag.Parse()

	if *inPkgJSON == "" {
		log.Fatalf("-in file must be specified %q %q", *inPkgJSON, *outPkgJSON)
	}
	if _, err := os.Stat(*inPkgJSON); err != nil {
		log.Fatalf("failed to find input package.json (%q): %v", *inPkgJSON, err)
	}

	out, err := run(*inPkgJSON)
	if err != nil {
		log.Fatal(err)
	}
	if *outPkgJSON != "" {
		if err := ioutil.WriteFile(*outPkgJSON, out, 0644); err != nil {
			log.Fatalf("writing jq output to %q failed: %v", out, err)
		}
	} else {
		fmt.Printf("%s", out)
	}
}

// run
func run(orgPkgJSON string) ([]byte, error) {
	workDir, err := ioutil.TempDir("", "goplssettings")
	if err != nil {
		return nil, err
	}
	log.Printf("WORK=%v", workDir)

	if !*work {
		defer os.RemoveAll(workDir)
	}

	api, err := readGoplsAPI()
	if err != nil {
		return nil, err
	}

	options, err := extractOptions(api)
	if err != nil {
		return nil, err
	}

	f, err := ioutil.TempFile(workDir, "gopls.settings")
	if err != nil {
		return nil, err
	}

	writeAsVSCodeSettings(f, options)

	if err := f.Close(); err != nil {
		return nil, err
	}

	return rewritePackageJSON(f.Name(), orgPkgJSON)
}

// readGoplsAPI returns the output of `gopls api-json`.
func readGoplsAPI() (*APIJSON, error) {
	version, err := exec.Command("gopls", "-v", "version").Output()
	if err != nil {
		return nil, fmt.Errorf("failed to check gopls version: %v", err)
	}
	log.Printf("Reading settings of gopls....\nversion:\n%s\n", version)

	out, err := exec.Command("gopls", "api-json").Output()
	if err != nil {
		return nil, fmt.Errorf("failed to run gopls: %v", err)
	}

	api := &APIJSON{}
	if err := json.Unmarshal(out, api); err != nil {
		return nil, fmt.Errorf("failed to unmarshal: %v", err)
	}
	return api, nil
}

// extractOptions extracts the options from APIJSON.
// It may rearrange the ordering and documentation for better presentation.
func extractOptions(api *APIJSON) ([]*OptionJSON, error) {
	type sortableOptionJSON struct {
		*OptionJSON
		section string
	}
	options := []sortableOptionJSON{}
	for k, v := range api.Options {
		for _, o := range v {
			options = append(options, sortableOptionJSON{OptionJSON: o, section: k})
		}
	}
	sort.SliceStable(options, func(i, j int) bool {
		return priority(options[i].section) < priority(options[j].section)
	})

	opts := []*OptionJSON{}
	for _, v := range options {
		if name := sectionName(v.section); name != "" {
			v.OptionJSON.Doc = name + " " + v.OptionJSON.Doc
		}
		opts = append(opts, v.OptionJSON)
	}
	return opts, nil
}

func priority(section string) int {
	switch section {
	case "User":
		return 0
	case "Experimental":
		return 10
	case "Debugging":
		return 100
	}
	return 1000
}

func sectionName(section string) string {
	switch section {
	case "Experimental":
		return "(Experimental)"
	case "Debugging":
		return "(For Debugging)"
	}
	return ""
}

// rewritePackageJSON rewrites the input package.json by running `jq`
// to update all existing gopls settings with the ones from the newSettings
// file.
func rewritePackageJSON(newSettings, inFile string) ([]byte, error) {
	prog := `walk(if type == "object" then with_entries(select(.key | test("^gopls.[a-z]") | not)) else . end) | .contributes.configuration.properties *= $GOPLS_SETTINGS[0]`

	cmd := exec.Command("jq", "--slurpfile", "GOPLS_SETTINGS", newSettings, prog, inFile)
	var stdout, stderr bytes.Buffer
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	if err := cmd.Run(); err != nil {
		return nil, fmt.Errorf("jq run failed (%v): %s", err, &stderr)
	}
	return stdout.Bytes(), nil
}

// convertToVSCodeSettings converts the options to the vscode setting format.
func writeAsVSCodeSettings(f io.Writer, options []*OptionJSON) {
	line := func(format string, args ...interface{}) {
		fmt.Fprintf(f, format, args...)
		fmt.Fprintln(f)
	}

	line(`{`)
	line(`"gopls": {`)
	line(`    "type": "object",`)
	line(`    "markdownDescription": "Configure the default Go language server ('gopls'). In most cases, configuring this section is unnecessary. See [the documentation](https://github.com/golang/tools/blob/master/gopls/doc/settings.md) for all available settings.",`)
	line(`    "scope": "resource",`)
	line(`    "additionalProperties": false,`)
	line(`    "properties": {`)
	for i, o := range options {
		line(`    "%v" : {`, o.Name)

		typ := propertyType(o.Type)
		line(`      "type": %q,`, typ)
		// TODO: consider 'additionalProperties' if gopls api-json outputs acceptable peoperties.

		line(`      "markdownDescription": %q,`, o.Doc)

		var enums, enumDocs []string
		for _, v := range o.EnumValues {
			enums = append(enums, v.Value)
			enumDocs = append(enumDocs, fmt.Sprintf("%q", v.Doc))
		}
		if len(enums) > 0 {
			line(`      "enum": [%v],`, strings.Join(enums, ","))
			line(`      "markdownEnumDescriptions": [%v],`, strings.Join(enumDocs, ","))
		}

		if len(o.Default) > 0 {
			line(`      "default": %v,`, o.Default)
		}

		// TODO: are all gopls settings in the resource scope?
		line(`      "scope": "resource"`)
		// TODO: deprecation attribute

		// "%v" : {
		if i == len(options)-1 {
			line(`    }`)
		} else {
			line(`    },`)
		}
	}
	line(`    }`) //  "properties": {
	line(`  }`)   // "gopls": {
	line(`}`)     // {
}

func propertyType(t string) string {
	switch t {
	case "string":
		return "string"
	case "bool":
		return "boolean"
	case "enum":
		return "string"
	case "time.Duration":
		return "string"
	case "[]string":
		return "array"
	case "map[string]string", "map[string]bool":
		return "object"
	}
	log.Fatalf("unknown type %q", t)
	return ""
}

func check(err error) {
	if err == nil {
		return
	}

	log.Output(1, err.Error())
	os.Exit(1)
}

// APIJSON is the output json type of `gopls api-json`.
// Types copied from golang.org/x/tools/internal/lsp/source/options.go.
type APIJSON struct {
	Options  map[string][]*OptionJSON
	Commands []*CommandJSON
	Lenses   []*LensJSON
}

type OptionJSON struct {
	Name       string
	Type       string
	Doc        string
	EnumValues []EnumValue
	Default    string
}

type EnumValue struct {
	Value string
	Doc   string
}

type CommandJSON struct {
	Command string
	Title   string
	Doc     string
}

type LensJSON struct {
	Lens  string
	Title string
	Doc   string
}
