// Copyright 2020 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.

// Command genopts generates JSON describing gopls' user options.
package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"go/ast"
	"go/types"
	"os"
	"reflect"
	"strings"

	"golang.org/x/tools/go/ast/astutil"
	"golang.org/x/tools/go/packages"
	"golang.org/x/tools/internal/lsp/source"
)

var (
	output = flag.String("output", "", "output file")
)

func main() {
	flag.Parse()
	if err := doMain(); err != nil {
		fmt.Fprintf(os.Stderr, "Generation failed: %v\n", err)
		os.Exit(1)
	}
}

func doMain() error {
	out := os.Stdout
	if *output != "" {
		var err error
		out, err = os.OpenFile(*output, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777)
		if err != nil {
			return err
		}
		defer out.Close()
	}

	content, err := generate()
	if err != nil {
		return err
	}
	if _, err := out.Write(content); err != nil {
		return err
	}

	return out.Close()
}

func generate() ([]byte, error) {
	pkgs, err := packages.Load(
		&packages.Config{
			Mode: packages.NeedTypes | packages.NeedSyntax | packages.NeedDeps,
		},
		"golang.org/x/tools/internal/lsp/source",
	)
	if err != nil {
		return nil, err
	}
	pkg := pkgs[0]

	defaults := source.DefaultOptions()
	categories := map[string][]option{}
	for _, cat := range []reflect.Value{
		reflect.ValueOf(defaults.DebuggingOptions),
		reflect.ValueOf(defaults.UserOptions),
		reflect.ValueOf(defaults.ExperimentalOptions),
	} {
		opts, err := loadOptions(cat, pkg)
		if err != nil {
			return nil, err
		}
		catName := strings.TrimSuffix(cat.Type().Name(), "Options")
		categories[catName] = opts
	}

	marshaled, err := json.Marshal(categories)
	if err != nil {
		return nil, err
	}

	buf := bytes.NewBuffer(nil)
	fmt.Fprintf(buf, "// Code generated by \"golang.org/x/tools/internal/lsp/source/genopts\"; DO NOT EDIT.\n\npackage source\n\nconst OptionsJson = %q\n", string(marshaled))
	return buf.Bytes(), nil
}

type option struct {
	Name    string
	Type    string
	Doc     string
	Default string
}

func loadOptions(category reflect.Value, pkg *packages.Package) ([]option, error) {
	// Find the type information and ast.File corresponding to the category.
	optsType := pkg.Types.Scope().Lookup(category.Type().Name())
	if optsType == nil {
		return nil, fmt.Errorf("could not find %v in scope %v", category.Type().Name(), pkg.Types.Scope())
	}

	fset := pkg.Fset
	var file *ast.File
	for _, f := range pkg.Syntax {
		if fset.Position(f.Pos()).Filename == fset.Position(optsType.Pos()).Filename {
			file = f
		}
	}
	if file == nil {
		return nil, fmt.Errorf("no file for opts type %v", optsType)
	}

	var opts []option
	optsStruct := optsType.Type().Underlying().(*types.Struct)
	for i := 0; i < optsStruct.NumFields(); i++ {
		// The types field gives us the type.
		typesField := optsStruct.Field(i)
		path, _ := astutil.PathEnclosingInterval(file, typesField.Pos(), typesField.Pos())
		if len(path) < 1 {
			return nil, fmt.Errorf("could not find AST node for field %v", typesField)
		}
		// The AST field gives us the doc.
		astField, ok := path[1].(*ast.Field)
		if !ok {
			return nil, fmt.Errorf("unexpected AST path %v", path)
		}

		// The reflect field gives us the default value.
		reflectField := category.FieldByName(typesField.Name())
		if !reflectField.IsValid() {
			return nil, fmt.Errorf("could not find reflect field for %v", typesField.Name())
		}

		// Format the default value. String values should look like strings. Other stuff should look like JSON literals.
		var defString string
		switch def := reflectField.Interface().(type) {
		case fmt.Stringer:
			defString = `"` + def.String() + `"`
		case string:
			defString = `"` + def + `"`
		default:
			defString = fmt.Sprint(def)
		}
		if reflectField.Kind() == reflect.Map {
			b, err := json.Marshal(reflectField.Interface())
			if err != nil {
				return nil, err
			}
			defString = string(b)
		}

		opts = append(opts, option{
			Name:    lowerFirst(typesField.Name()),
			Type:    typesField.Type().String(),
			Doc:     lowerFirst(astField.Doc.Text()),
			Default: defString,
		})
	}
	return opts, nil
}

func lowerFirst(x string) string {
	if x == "" {
		return x
	}
	return strings.ToLower(x[:1]) + x[1:]
}
