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

package settings

import (
	"fmt"
	"maps"
	"path/filepath"
	"strings"
	"time"

	"golang.org/x/tools/gopls/internal/file"
	"golang.org/x/tools/gopls/internal/protocol"
	"golang.org/x/tools/gopls/internal/protocol/semtok"
	"golang.org/x/tools/gopls/internal/util/frob"
)

// Options holds various configuration that affects Gopls execution, organized
// by the nature or origin of the settings.
//
// Options must be comparable with reflect.DeepEqual, and serializable with
// [frob.Codec].
//
// This type defines both the logic of LSP-supplied option parsing
// (see [SetOptions]), and the public documentation of options in
// ../../doc/settings.md (generated by gopls/doc/generate).
//
// Each exported field of each embedded type such as "ClientOptions"
// contributes a user-visible option setting. The option name is the
// field name rendered in camelCase. Unlike most Go doc comments,
// these fields should be documented using GitHub markdown.
type Options struct {
	ClientOptions
	ServerOptions
	UserOptions
	InternalOptions
}

// ClientOptions holds LSP-specific configuration that is provided by the
// client.
//
// ClientOptions must be comparable with reflect.DeepEqual.
type ClientOptions struct {
	ClientInfo                                 protocol.ClientInfo
	InsertTextFormat                           protocol.InsertTextFormat
	InsertReplaceSupported                     bool
	ConfigurationSupported                     bool
	DynamicConfigurationSupported              bool
	DynamicRegistrationSemanticTokensSupported bool
	DynamicWatchedFilesSupported               bool
	RelativePatternsSupported                  bool
	PreferredContentFormat                     protocol.MarkupKind
	LineFoldingOnly                            bool
	HierarchicalDocumentSymbolSupport          bool
	ImportsSource                              ImportsSourceEnum `status:"experimental"`
	SemanticTypes                              []string
	SemanticMods                               []string
	RelatedInformationSupported                bool
	CompletionTags                             bool
	CompletionDeprecated                       bool
	SupportedResourceOperations                []protocol.ResourceOperationKind
	CodeActionResolveOptions                   []string
	ShowDocumentSupported                      bool
}

// ServerOptions holds LSP-specific configuration that is provided by the
// server.
//
// ServerOptions must be comparable with reflect.DeepEqual.
type ServerOptions struct {
	SupportedCodeActions map[file.Kind]map[protocol.CodeActionKind]bool
	SupportedCommands    []string
}

// Note: BuildOptions must be comparable with reflect.DeepEqual.
type BuildOptions struct {
	// BuildFlags is the set of flags passed on to the build system when invoked.
	// It is applied to queries like `go list`, which is used when discovering files.
	// The most common use is to set `-tags`.
	BuildFlags []string

	// Env adds environment variables to external commands run by `gopls`, most notably `go list`.
	Env map[string]string

	// DirectoryFilters can be used to exclude unwanted directories from the
	// workspace. By default, all directories are included. Filters are an
	// operator, `+` to include and `-` to exclude, followed by a path prefix
	// relative to the workspace folder. They are evaluated in order, and
	// the last filter that applies to a path controls whether it is included.
	// The path prefix can be empty, so an initial `-` excludes everything.
	//
	// DirectoryFilters also supports the `**` operator to match 0 or more directories.
	//
	// Examples:
	//
	// Exclude node_modules at current depth: `-node_modules`
	//
	// Exclude node_modules at any depth: `-**/node_modules`
	//
	// Include only project_a: `-` (exclude everything), `+project_a`
	//
	// Include only project_a, but not node_modules inside it: `-`, `+project_a`, `-project_a/node_modules`
	DirectoryFilters []string

	// TemplateExtensions gives the extensions of file names that are treated
	// as template files. (The extension
	// is the part of the file name after the final dot.)
	TemplateExtensions []string

	// obsolete, no effect
	MemoryMode string `status:"experimental"`

	// ExpandWorkspaceToModule determines which packages are considered
	// "workspace packages" when the workspace is using modules.
	//
	// Workspace packages affect the scope of workspace-wide operations. Notably,
	// gopls diagnoses all packages considered to be part of the workspace after
	// every keystroke, so by setting "ExpandWorkspaceToModule" to false, and
	// opening a nested workspace directory, you can reduce the amount of work
	// gopls has to do to keep your workspace up to date.
	ExpandWorkspaceToModule bool `status:"experimental"`

	// StandaloneTags specifies a set of build constraints that identify
	// individual Go source files that make up the entire main package of an
	// executable.
	//
	// A common example of standalone main files is the convention of using the
	// directive `//go:build ignore` to denote files that are not intended to be
	// included in any package, for example because they are invoked directly by
	// the developer using `go run`.
	//
	// Gopls considers a file to be a standalone main file if and only if it has
	// package name "main" and has a build directive of the exact form
	// "//go:build tag" or "// +build tag", where tag is among the list of tags
	// configured by this setting. Notably, if the build constraint is more
	// complicated than a simple tag (such as the composite constraint
	// `//go:build tag && go1.18`), the file is not considered to be a standalone
	// main file.
	//
	// This setting is only supported when gopls is built with Go 1.16 or later.
	StandaloneTags []string

	// WorkspaceFiles configures the set of globs that match files defining the logical build of the current workspace.
	// Any on-disk changes to any files matching a glob specified here will trigger a reload of the workspace.
	//
	// This setting need only be customized in environments with a custom GOPACKAGESDRIVER.
	WorkspaceFiles []string
}

// Note: UIOptions must be comparable with reflect.DeepEqual.
type UIOptions struct {
	DocumentationOptions
	CompletionOptions
	NavigationOptions
	DiagnosticOptions
	InlayHintOptions

	// Codelenses overrides the enabled/disabled state of each of gopls'
	// sources of [Code Lenses](codelenses.md).
	//
	// Example Usage:
	//
	// ```json5
	// "gopls": {
	// ...
	//   "codelenses": {
	//     "generate": false,  // Don't show the `go generate` lens.
	//   }
	// ...
	// }
	// ```
	Codelenses map[CodeLensSource]bool

	// SemanticTokens controls whether the LSP server will send
	// semantic tokens to the client.
	SemanticTokens bool `status:"experimental"`

	// NoSemanticString turns off the sending of the semantic token 'string'
	//
	// Deprecated: Use SemanticTokenTypes["string"] = false instead. See
	// golang/vscode-go#3632
	NoSemanticString bool `status:"experimental"`

	// NoSemanticNumber turns off the sending of the semantic token 'number'
	//
	// Deprecated: Use SemanticTokenTypes["number"] = false instead. See
	// golang/vscode-go#3632.
	NoSemanticNumber bool `status:"experimental"`

	// SemanticTokenTypes configures the semantic token types. It allows
	// disabling types by setting each value to false.
	// By default, all types are enabled.
	SemanticTokenTypes map[string]bool `status:"experimental"`

	// SemanticTokenModifiers configures the semantic token modifiers. It allows
	// disabling modifiers by setting each value to false.
	// By default, all modifiers are enabled.
	SemanticTokenModifiers map[string]bool `status:"experimental"`
}

// A CodeLensSource identifies an (algorithmic) source of code lenses.
type CodeLensSource string

// CodeLens sources
//
// These identifiers appear in the "codelenses" configuration setting,
// and in the user documentation thereof, which is generated by
// gopls/doc/generate/generate.go parsing this file.
//
// Doc comments should use GitHub Markdown.
// The first line becomes the title.
//
// (For historical reasons, each code lens source identifier typically
// matches the name of one of the command.Commands returned by it,
// but that isn't essential.)
const (
	// Run `go generate`
	//
	// This codelens source annotates any `//go:generate` comments
	// with commands to run `go generate` in this directory, on
	// all directories recursively beneath this one.
	//
	// See [Generating code](https://go.dev/blog/generate) for
	// more details.
	CodeLensGenerate CodeLensSource = "generate"

	// Re-generate cgo declarations
	//
	// This codelens source annotates an `import "C"` declaration
	// with a command to re-run the [cgo
	// command](https://pkg.go.dev/cmd/cgo) to regenerate the
	// corresponding Go declarations.
	//
	// Use this after editing the C code in comments attached to
	// the import, or in C header files included by it.
	CodeLensRegenerateCgo CodeLensSource = "regenerate_cgo"

	// Run govulncheck
	//
	// This codelens source annotates the `module` directive in a go.mod file
	// with a command to run govulncheck synchronously.
	//
	// [Govulncheck](https://go.dev/blog/vuln) is a static analysis tool that
	// computes the set of functions reachable within your application, including
	// dependencies; queries a database of known security vulnerabilities; and
	// reports any potential problems it finds.
	CodeLensVulncheck CodeLensSource = "vulncheck"

	// Run govulncheck (legacy)
	//
	// This codelens source annotates the `module` directive in a go.mod file
	// with a command to run Govulncheck asynchronously.
	//
	// [Govulncheck](https://go.dev/blog/vuln) is a static analysis tool that
	// computes the set of functions reachable within your application, including
	// dependencies; queries a database of known security vulnerabilities; and
	// reports any potential problems it finds.
	CodeLensRunGovulncheck CodeLensSource = "run_govulncheck"

	// Run tests and benchmarks
	//
	// This codelens source annotates each `Test` and `Benchmark`
	// function in a `*_test.go` file with a command to run it.
	//
	// This source is off by default because VS Code has
	// a client-side custom UI for testing, and because progress
	// notifications are not a great UX for streamed test output.
	// See:
	// - golang/go#67400 for a discussion of this feature.
	// - https://github.com/joaotavora/eglot/discussions/1402
	//   for an alternative approach.
	CodeLensTest CodeLensSource = "test"

	// Tidy go.mod file
	//
	// This codelens source annotates the `module` directive in a
	// go.mod file with a command to run [`go mod
	// tidy`](https://go.dev/ref/mod#go-mod-tidy), which ensures
	// that the go.mod file matches the source code in the module.
	CodeLensTidy CodeLensSource = "tidy"

	// Update dependencies
	//
	// This codelens source annotates the `module` directive in a
	// go.mod file with commands to:
	//
	// - check for available upgrades,
	// - upgrade direct dependencies, and
	// - upgrade all dependencies transitively.
	CodeLensUpgradeDependency CodeLensSource = "upgrade_dependency"

	// Update vendor directory
	//
	// This codelens source annotates the `module` directive in a
	// go.mod file with a command to run [`go mod
	// vendor`](https://go.dev/ref/mod#go-mod-vendor), which
	// creates or updates the directory named `vendor` in the
	// module root so that it contains an up-to-date copy of all
	// necessary package dependencies.
	CodeLensVendor CodeLensSource = "vendor"
)

// Note: CompletionOptions must be comparable with reflect.DeepEqual.
type CompletionOptions struct {
	// Placeholders enables placeholders for function parameters or struct
	// fields in completion responses.
	UsePlaceholders bool

	// CompletionBudget is the soft latency goal for completion requests. Most
	// requests finish in a couple milliseconds, but in some cases deep
	// completions can take much longer. As we use up our budget we
	// dynamically reduce the search scope to ensure we return timely
	// results. Zero means unlimited.
	CompletionBudget time.Duration `status:"debug"`

	// Matcher sets the algorithm that is used when calculating completion
	// candidates.
	Matcher Matcher `status:"advanced"`

	// ExperimentalPostfixCompletions enables artificial method snippets
	// such as "someSlice.sort!".
	ExperimentalPostfixCompletions bool `status:"experimental"`

	// CompleteFunctionCalls enables function call completion.
	//
	// When completing a statement, or when a function return type matches the
	// expected of the expression being completed, completion may suggest call
	// expressions (i.e. may include parentheses).
	CompleteFunctionCalls bool
}

// Note: DocumentationOptions must be comparable with reflect.DeepEqual.
type DocumentationOptions struct {
	// HoverKind controls the information that appears in the hover text.
	// SingleLine is intended for use only by authors of editor plugins.
	HoverKind HoverKind

	// LinkTarget is the base URL for links to Go package
	// documentation returned by LSP operations such as Hover and
	// DocumentLinks and in the CodeDescription field of each
	// Diagnostic.
	//
	// It might be one of:
	//
	// * `"godoc.org"`
	// * `"pkg.go.dev"`
	//
	// If company chooses to use its own `godoc.org`, its address can be used as well.
	//
	// Modules matching the GOPRIVATE environment variable will not have
	// documentation links in hover.
	LinkTarget string

	// LinksInHover controls the presence of documentation links in hover markdown.
	LinksInHover LinksInHoverEnum
}

// LinksInHoverEnum has legal values:
//
// - `false`, for no links;
// - `true`, for links to the `linkTarget` domain; or
// - `"gopls"`, for links to gopls' internal documentation viewer.
//
// Note: this type has special logic in loadEnums in generate.go.
// Be sure to reflect enum and doc changes there!
type LinksInHoverEnum int

const (
	LinksInHover_None LinksInHoverEnum = iota
	LinksInHover_LinkTarget
	LinksInHover_Gopls
)

// MarshalJSON implements the json.Marshaler interface, so that the default
// values are formatted correctly in documentation. (See [Options.setOne] for
// the flexible custom unmarshalling behavior).
func (l LinksInHoverEnum) MarshalJSON() ([]byte, error) {
	switch l {
	case LinksInHover_None:
		return []byte("false"), nil
	case LinksInHover_LinkTarget:
		return []byte("true"), nil
	case LinksInHover_Gopls:
		return []byte(`"gopls"`), nil
	default:
		return nil, fmt.Errorf("invalid LinksInHover value %d", l)
	}
}

// Note: FormattingOptions must be comparable with reflect.DeepEqual.
type FormattingOptions struct {
	// Local is the equivalent of the `goimports -local` flag, which puts
	// imports beginning with this string after third-party packages. It should
	// be the prefix of the import path whose imports should be grouped
	// separately.
	//
	// It is used when tidying imports (during an LSP Organize
	// Imports request) or when inserting new ones (for example,
	// during completion); an LSP Formatting request merely sorts the
	// existing imports.
	Local string

	// Gofumpt indicates if we should run gofumpt formatting.
	Gofumpt bool
}

// Note: DiagnosticOptions must be comparable with reflect.DeepEqual.
type DiagnosticOptions struct {
	// Analyses specify analyses that the user would like to enable or disable.
	// A map of the names of analysis passes that should be enabled/disabled.
	// A full list of analyzers that gopls uses can be found in
	// [analyzers.md](https://github.com/golang/tools/blob/master/gopls/doc/analyzers.md).
	//
	// Example Usage:
	//
	// ```json5
	// ...
	// "analyses": {
	//   "unreachable": false, // Disable the unreachable analyzer.
	//   "unusedvariable": true  // Enable the unusedvariable analyzer.
	// }
	// ...
	// ```
	Analyses map[string]bool

	// Staticcheck enables additional analyses from staticcheck.io.
	// These analyses are documented on
	// [Staticcheck's website](https://staticcheck.io/docs/checks/).
	Staticcheck bool `status:"experimental"`

	// Vulncheck enables vulnerability scanning.
	Vulncheck VulncheckMode `status:"experimental"`

	// DiagnosticsDelay controls the amount of time that gopls waits
	// after the most recent file modification before computing deep diagnostics.
	// Simple diagnostics (parsing and type-checking) are always run immediately
	// on recently modified packages.
	//
	// This option must be set to a valid duration string, for example `"250ms"`.
	DiagnosticsDelay time.Duration `status:"advanced"`

	// DiagnosticsTrigger controls when to run diagnostics.
	DiagnosticsTrigger DiagnosticsTrigger `status:"experimental"`

	// AnalysisProgressReporting controls whether gopls sends progress
	// notifications when construction of its index of analysis facts is taking a
	// long time. Cancelling these notifications will cancel the indexing task,
	// though it will restart after the next change in the workspace.
	//
	// When a package is opened for the first time and heavyweight analyses such as
	// staticcheck are enabled, it can take a while to construct the index of
	// analysis facts for all its dependencies. The index is cached in the
	// filesystem, so subsequent analysis should be faster.
	AnalysisProgressReporting bool
}

type InlayHintOptions struct {
	// Hints specify inlay hints that users want to see. A full list of hints
	// that gopls uses can be found in
	// [inlayHints.md](https://github.com/golang/tools/blob/master/gopls/doc/inlayHints.md).
	Hints map[InlayHint]bool `status:"experimental"`
}

// An InlayHint identifies a category of hint that may be
// independently requested through the "hints" setting.
type InlayHint string

// This is the source from which gopls/doc/inlayHints.md is generated.
const (
	// ParameterNames controls inlay hints for parameter names:
	// ```go
	// 	parseInt(/* str: */ "123", /* radix: */ 8)
	// ```
	ParameterNames InlayHint = "parameterNames"

	// AssignVariableTypes controls inlay hints for variable types in assign statements:
	// ```go
	// 	i/* int*/, j/* int*/ := 0, len(r)-1
	// ```
	AssignVariableTypes InlayHint = "assignVariableTypes"

	// ConstantValues controls inlay hints for constant values:
	// ```go
	// 	const (
	// 		KindNone   Kind = iota/* = 0*/
	// 		KindPrint/*  = 1*/
	// 		KindPrintf/* = 2*/
	// 		KindErrorf/* = 3*/
	// 	)
	// ```
	ConstantValues InlayHint = "constantValues"

	// RangeVariableTypes controls inlay hints for variable types in range statements:
	// ```go
	// 	for k/* int*/, v/* string*/ := range []string{} {
	// 		fmt.Println(k, v)
	// 	}
	// ```
	RangeVariableTypes InlayHint = "rangeVariableTypes"

	// CompositeLiteralTypes controls inlay hints for composite literal types:
	// ```go
	// 	for _, c := range []struct {
	// 		in, want string
	// 	}{
	// 		/*struct{ in string; want string }*/{"Hello, world", "dlrow ,olleH"},
	// 	}
	// ```
	CompositeLiteralTypes InlayHint = "compositeLiteralTypes"

	// CompositeLiteralFieldNames inlay hints for composite literal field names:
	// ```go
	// 	{/*in: */"Hello, world", /*want: */"dlrow ,olleH"}
	// ```
	CompositeLiteralFieldNames InlayHint = "compositeLiteralFields"

	// FunctionTypeParameters inlay hints for implicit type parameters on generic functions:
	// ```go
	// 	myFoo/*[int, string]*/(1, "hello")
	// ```
	FunctionTypeParameters InlayHint = "functionTypeParameters"
)

type NavigationOptions struct {
	// ImportShortcut specifies whether import statements should link to
	// documentation or go to definitions.
	ImportShortcut ImportShortcut

	// SymbolMatcher sets the algorithm that is used when finding workspace symbols.
	SymbolMatcher SymbolMatcher `status:"advanced"`

	// SymbolStyle controls how symbols are qualified in symbol responses.
	//
	// Example Usage:
	//
	// ```json5
	// "gopls": {
	// ...
	//   "symbolStyle": "Dynamic",
	// ...
	// }
	// ```
	SymbolStyle SymbolStyle `status:"advanced"`

	// SymbolScope controls which packages are searched for workspace/symbol
	// requests. When the scope is "workspace", gopls searches only workspace
	// packages. When the scope is "all", gopls searches all loaded packages,
	// including dependencies and the standard library.
	SymbolScope SymbolScope
}

// UserOptions holds custom Gopls configuration (not part of the LSP) that is
// modified by the client.
//
// UserOptions must be comparable with reflect.DeepEqual.
type UserOptions struct {
	BuildOptions
	UIOptions
	FormattingOptions

	// VerboseOutput enables additional debug logging.
	VerboseOutput bool `status:"debug"`
}

// EnvSlice returns Env as a slice of k=v strings.
func (u *UserOptions) EnvSlice() []string {
	var result []string
	for k, v := range u.Env {
		result = append(result, fmt.Sprintf("%v=%v", k, v))
	}
	return result
}

// SetEnvSlice sets Env from a slice of k=v strings.
func (u *UserOptions) SetEnvSlice(env []string) {
	u.Env = map[string]string{}
	for _, kv := range env {
		split := strings.SplitN(kv, "=", 2)
		if len(split) != 2 {
			continue
		}
		u.Env[split[0]] = split[1]
	}
}

// InternalOptions contains settings that are not intended for use by the
// average user. These may be settings used by tests or outdated settings that
// will soon be deprecated. Some of these settings may not even be configurable
// by the user.
//
// TODO(rfindley): even though these settings are not intended for
// modification, some of them should be surfaced in our documentation.
type InternalOptions struct {
	// VerboseWorkDoneProgress controls whether the LSP server should send
	// progress reports for all work done outside the scope of an RPC.
	// Used by the regression tests.
	VerboseWorkDoneProgress bool

	// The following options were previously available to users, but they
	// really shouldn't be configured by anyone other than "power users".

	// CompletionDocumentation enables documentation with completion results.
	CompletionDocumentation bool

	// CompleteUnimported enables completion for packages that you do not
	// currently import.
	CompleteUnimported bool

	// DeepCompletion enables the ability to return completions from deep
	// inside relevant entities, rather than just the locally accessible ones.
	//
	// Consider this example:
	//
	// ```go
	// package main
	//
	// import "fmt"
	//
	// type wrapString struct {
	//     str string
	// }
	//
	// func main() {
	//     x := wrapString{"hello world"}
	//     fmt.Printf(<>)
	// }
	// ```
	//
	// At the location of the `<>` in this program, deep completion would suggest
	// the result `x.str`.
	DeepCompletion bool

	// ShowBugReports causes a message to be shown when the first bug is reported
	// on the server.
	// This option applies only during initialization.
	ShowBugReports bool

	// SubdirWatchPatterns configures the file watching glob patterns registered
	// by gopls.
	//
	// Some clients (namely VS Code) do not send workspace/didChangeWatchedFile
	// notifications for files contained in a directory when that directory is
	// deleted:
	// https://github.com/microsoft/vscode/issues/109754
	//
	// In this case, gopls would miss important notifications about deleted
	// packages. To work around this, gopls registers a watch pattern for each
	// directory containing Go files.
	//
	// Unfortunately, other clients experience performance problems with this
	// many watch patterns, so there is no single behavior that works well for
	// all clients.
	//
	// The "subdirWatchPatterns" setting allows configuring this behavior. Its
	// default value of "auto" attempts to guess the correct behavior based on
	// the client name. We'd love to avoid this specialization, but as described
	// above there is no single value that works for all clients.
	//
	// If any LSP client does not behave well with the default value (for
	// example, if like VS Code it drops file notifications), please file an
	// issue.
	SubdirWatchPatterns SubdirWatchPatterns

	// ReportAnalysisProgressAfter sets the duration for gopls to wait before starting
	// progress reporting for ongoing go/analysis passes.
	//
	// It is intended to be used for testing only.
	ReportAnalysisProgressAfter time.Duration

	// TelemetryPrompt controls whether gopls prompts about enabling Go telemetry.
	//
	// Once the prompt is answered, gopls doesn't ask again, but TelemetryPrompt
	// can prevent the question from ever being asked in the first place.
	TelemetryPrompt bool

	// LinkifyShowMessage controls whether the client wants gopls
	// to linkify links in showMessage. e.g. [go.dev](https://go.dev).
	LinkifyShowMessage bool

	// IncludeReplaceInWorkspace controls whether locally replaced modules in a
	// go.mod file are treated like workspace modules.
	// Or in other words, if a go.mod file with local replaces behaves like a
	// go.work file.
	IncludeReplaceInWorkspace bool

	// ZeroConfig enables the zero-config algorithm for workspace layout,
	// dynamically creating build configurations for different modules,
	// directories, and GOOS/GOARCH combinations to cover open files.
	ZeroConfig bool

	// PullDiagnostics enables support for pull diagnostics.
	//
	// TODO(rfindley): make pull diagnostics robust, and remove this option,
	// allowing pull diagnostics by default.
	PullDiagnostics bool
}

type SubdirWatchPatterns string

const (
	SubdirWatchPatternsOn   SubdirWatchPatterns = "on"
	SubdirWatchPatternsOff  SubdirWatchPatterns = "off"
	SubdirWatchPatternsAuto SubdirWatchPatterns = "auto"
)

type ImportShortcut string

const (
	BothShortcuts      ImportShortcut = "Both"
	LinkShortcut       ImportShortcut = "Link"
	DefinitionShortcut ImportShortcut = "Definition"
)

func (s ImportShortcut) ShowLinks() bool {
	return s == BothShortcuts || s == LinkShortcut
}

func (s ImportShortcut) ShowDefinition() bool {
	return s == BothShortcuts || s == DefinitionShortcut
}

// ImportsSourceEnum has legal values:
//
// - `off` to disable searching the file system for imports
// - `gopls` to use the metadata graph and module cache index
// - `goimports` for the old behavior, to be deprecated
type ImportsSourceEnum string

const (
	ImportsSourceOff       ImportsSourceEnum = "off"
	ImportsSourceGopls                       = "gopls"
	ImportsSourceGoimports                   = "goimports"
)

type Matcher string

const (
	Fuzzy           Matcher = "Fuzzy"
	CaseInsensitive Matcher = "CaseInsensitive"
	CaseSensitive   Matcher = "CaseSensitive"
)

// A SymbolMatcher controls the matching of symbols for workspace/symbol
// requests.
type SymbolMatcher string

const (
	SymbolFuzzy           SymbolMatcher = "Fuzzy"
	SymbolFastFuzzy       SymbolMatcher = "FastFuzzy"
	SymbolCaseInsensitive SymbolMatcher = "CaseInsensitive"
	SymbolCaseSensitive   SymbolMatcher = "CaseSensitive"
)

// A SymbolStyle controls the formatting of symbols in workspace/symbol results.
type SymbolStyle string

const (
	// PackageQualifiedSymbols is package qualified symbols i.e.
	// "pkg.Foo.Field".
	PackageQualifiedSymbols SymbolStyle = "Package"
	// FullyQualifiedSymbols is fully qualified symbols, i.e.
	// "path/to/pkg.Foo.Field".
	FullyQualifiedSymbols SymbolStyle = "Full"
	// DynamicSymbols uses whichever qualifier results in the highest scoring
	// match for the given symbol query. Here a "qualifier" is any "/" or "."
	// delimited suffix of the fully qualified symbol. i.e. "to/pkg.Foo.Field" or
	// just "Foo.Field".
	DynamicSymbols SymbolStyle = "Dynamic"
)

// A SymbolScope controls the search scope for workspace/symbol requests.
type SymbolScope string

const (
	// WorkspaceSymbolScope matches symbols in workspace packages only.
	WorkspaceSymbolScope SymbolScope = "workspace"
	// AllSymbolScope matches symbols in any loaded package, including
	// dependencies.
	AllSymbolScope SymbolScope = "all"
)

type HoverKind string

const (
	SingleLine            HoverKind = "SingleLine"
	NoDocumentation       HoverKind = "NoDocumentation"
	SynopsisDocumentation HoverKind = "SynopsisDocumentation"
	FullDocumentation     HoverKind = "FullDocumentation"
)

type VulncheckMode string

const (
	// Disable vulnerability analysis.
	ModeVulncheckOff VulncheckMode = "Off"
	// In Imports mode, `gopls` will report vulnerabilities that affect packages
	// directly and indirectly used by the analyzed main module.
	ModeVulncheckImports VulncheckMode = "Imports"

	// TODO: VulncheckRequire, VulncheckCallgraph
)

type DiagnosticsTrigger string

const (
	// Trigger diagnostics on file edit and save. (default)
	DiagnosticsOnEdit DiagnosticsTrigger = "Edit"
	// Trigger diagnostics only on file save. Events like initial workspace load
	// or configuration change will still trigger diagnostics.
	DiagnosticsOnSave DiagnosticsTrigger = "Save"
	// TODO: support "Manual"?
)

// Set updates *options based on the provided JSON value:
// null, bool, string, number, array, or object.
// On failure, it returns one or more non-nil errors.
func (o *Options) Set(value any) (errors []error) {
	switch value := value.(type) {
	case nil:
	case map[string]any:
		seen := make(map[string]struct{})
		for name, value := range value {
			// Use only the last segment of a dotted name such as
			// ui.navigation.symbolMatcher. The other segments
			// are discarded, even without validation (!).
			// (They are supported to enable hierarchical names
			// in the VS Code graphical configuration UI.)
			split := strings.Split(name, ".")
			name = split[len(split)-1]

			if _, ok := seen[name]; ok {
				errors = append(errors, fmt.Errorf("duplicate value for %s", name))
			}
			seen[name] = struct{}{}

			if err := o.setOne(name, value); err != nil {
				err := fmt.Errorf("setting option %q: %w", name, err)
				errors = append(errors, err)
			}
		}
	default:
		errors = append(errors, fmt.Errorf("invalid options type %T (want JSON null or object)", value))
	}
	return errors
}

func (o *Options) ForClientCapabilities(clientInfo *protocol.ClientInfo, caps protocol.ClientCapabilities) {
	if clientInfo != nil {
		o.ClientInfo = *clientInfo
	}
	if caps.Workspace.WorkspaceEdit != nil {
		o.SupportedResourceOperations = caps.Workspace.WorkspaceEdit.ResourceOperations
	}
	// Check if the client supports snippets in completion items.
	if c := caps.TextDocument.Completion; c.CompletionItem.SnippetSupport {
		o.InsertTextFormat = protocol.SnippetTextFormat
	}
	o.InsertReplaceSupported = caps.TextDocument.Completion.CompletionItem.InsertReplaceSupport
	if caps.Window.ShowDocument != nil {
		o.ShowDocumentSupported = caps.Window.ShowDocument.Support
	}
	// Check if the client supports configuration messages.
	o.ConfigurationSupported = caps.Workspace.Configuration
	o.DynamicConfigurationSupported = caps.Workspace.DidChangeConfiguration.DynamicRegistration
	o.DynamicRegistrationSemanticTokensSupported = caps.TextDocument.SemanticTokens.DynamicRegistration
	o.DynamicWatchedFilesSupported = caps.Workspace.DidChangeWatchedFiles.DynamicRegistration
	o.RelativePatternsSupported = caps.Workspace.DidChangeWatchedFiles.RelativePatternSupport

	// Check which types of content format are supported by this client.
	if hover := caps.TextDocument.Hover; hover != nil && len(hover.ContentFormat) > 0 {
		o.PreferredContentFormat = hover.ContentFormat[0]
	}
	// Check if the client supports only line folding.

	if fr := caps.TextDocument.FoldingRange; fr != nil {
		o.LineFoldingOnly = fr.LineFoldingOnly
	}
	// Check if the client supports hierarchical document symbols.
	o.HierarchicalDocumentSymbolSupport = caps.TextDocument.DocumentSymbol.HierarchicalDocumentSymbolSupport

	// Client's semantic tokens
	o.SemanticTypes = caps.TextDocument.SemanticTokens.TokenTypes
	o.SemanticMods = caps.TextDocument.SemanticTokens.TokenModifiers
	// we don't need Requests, as we support full functionality
	// we don't need Formats, as there is only one, for now

	// Check if the client supports diagnostic related information.
	o.RelatedInformationSupported = caps.TextDocument.PublishDiagnostics.RelatedInformation
	// Check if the client completion support includes tags (preferred) or deprecation
	if caps.TextDocument.Completion.CompletionItem.TagSupport != nil &&
		caps.TextDocument.Completion.CompletionItem.TagSupport.ValueSet != nil {
		o.CompletionTags = true
	} else if caps.TextDocument.Completion.CompletionItem.DeprecatedSupport {
		o.CompletionDeprecated = true
	}

	// Check if the client supports code actions resolving.
	if caps.TextDocument.CodeAction.DataSupport && caps.TextDocument.CodeAction.ResolveSupport != nil {
		o.CodeActionResolveOptions = caps.TextDocument.CodeAction.ResolveSupport.Properties
	}
}

var codec = frob.CodecFor[*Options]()

func (o *Options) Clone() *Options {
	data := codec.Encode(o)
	var clone *Options
	codec.Decode(data, &clone)
	return clone
}

// validateDirectoryFilter validates if the filter string
// - is not empty
// - start with either + or -
// - doesn't contain currently unsupported glob operators: *, ?
func validateDirectoryFilter(ifilter string) (string, error) {
	filter := fmt.Sprint(ifilter)
	if filter == "" || (filter[0] != '+' && filter[0] != '-') {
		return "", fmt.Errorf("invalid filter %v, must start with + or -", filter)
	}
	segs := strings.Split(filter[1:], "/")
	unsupportedOps := [...]string{"?", "*"}
	for _, seg := range segs {
		if seg != "**" {
			for _, op := range unsupportedOps {
				if strings.Contains(seg, op) {
					return "", fmt.Errorf("invalid filter %v, operator %v not supported. If you want to have this operator supported, consider filing an issue.", filter, op)
				}
			}
		}
	}

	return strings.TrimRight(filepath.FromSlash(filter), "/"), nil
}

// setOne updates a field of o based on the name and value.
// It returns an error if the value was invalid or duplicate.
// It is the caller's responsibility to augment the error with 'name'.
func (o *Options) setOne(name string, value any) error {
	switch name {
	case "env":
		env, ok := value.(map[string]any)
		if !ok {
			return fmt.Errorf("invalid type %T (want JSON object)", value)
		}
		if o.Env == nil {
			o.Env = make(map[string]string)
		}
		for k, v := range env {
			// For historic compatibility, we accept int too (e.g. CGO_ENABLED=1).
			switch v.(type) {
			case string, int:
				o.Env[k] = fmt.Sprint(v)
			default:
				return fmt.Errorf("invalid map value %T (want string)", v)
			}
		}

	case "buildFlags":
		return setStringSlice(&o.BuildFlags, value)

	case "directoryFilters":
		filterStrings, err := asStringSlice(value)
		if err != nil {
			return err
		}
		var filters []string
		for _, filterStr := range filterStrings {
			filter, err := validateDirectoryFilter(filterStr)
			if err != nil {
				return err
			}
			filters = append(filters, strings.TrimRight(filepath.FromSlash(filter), "/"))
		}
		o.DirectoryFilters = filters

	case "workspaceFiles":
		return setStringSlice(&o.WorkspaceFiles, value)
	case "completionDocumentation":
		return setBool(&o.CompletionDocumentation, value)
	case "usePlaceholders":
		return setBool(&o.UsePlaceholders, value)
	case "deepCompletion":
		return setBool(&o.DeepCompletion, value)
	case "completeUnimported":
		return setBool(&o.CompleteUnimported, value)
	case "completionBudget":
		return setDuration(&o.CompletionBudget, value)
	case "importsSource":
		return setEnum(&o.ImportsSource, value,
			ImportsSourceOff,
			ImportsSourceGopls,
			ImportsSourceGoimports)
	case "matcher":
		return setEnum(&o.Matcher, value,
			Fuzzy,
			CaseSensitive,
			CaseInsensitive)

	case "symbolMatcher":
		return setEnum(&o.SymbolMatcher, value,
			SymbolFuzzy,
			SymbolFastFuzzy,
			SymbolCaseInsensitive,
			SymbolCaseSensitive)

	case "symbolStyle":
		return setEnum(&o.SymbolStyle, value,
			FullyQualifiedSymbols,
			PackageQualifiedSymbols,
			DynamicSymbols)

	case "symbolScope":
		return setEnum(&o.SymbolScope, value,
			WorkspaceSymbolScope,
			AllSymbolScope)

	case "hoverKind":
		if s, ok := value.(string); ok && strings.EqualFold(s, "structured") {
			return deprecatedError("the experimental hoverKind='structured' setting was removed in gopls/v0.18.0 (https://go.dev/issue/70233)")
		}
		return setEnum(&o.HoverKind, value,
			NoDocumentation,
			SingleLine,
			SynopsisDocumentation,
			FullDocumentation)

	case "linkTarget":
		return setString(&o.LinkTarget, value)

	case "linksInHover":
		switch value {
		case false:
			o.LinksInHover = LinksInHover_None
		case true:
			o.LinksInHover = LinksInHover_LinkTarget
		case "gopls":
			o.LinksInHover = LinksInHover_Gopls
		default:
			return fmt.Errorf(`invalid value %s; expect false, true, or "gopls"`,
				value)
		}

	case "importShortcut":
		return setEnum(&o.ImportShortcut, value,
			BothShortcuts,
			LinkShortcut,
			DefinitionShortcut)

	case "analyses":
		if err := setBoolMap(&o.Analyses, value); err != nil {
			return err
		}
		if o.Analyses["fieldalignment"] {
			return deprecatedError("the 'fieldalignment' analyzer was removed in gopls/v0.17.0; instead, hover over struct fields to see size/offset information (https://go.dev/issue/66861)")
		}

	case "hints":
		return setBoolMap(&o.Hints, value)

	case "annotations":
		return deprecatedError("the 'annotations' setting was removed in gopls/v0.18.0; all compiler optimization details are now shown")

	case "vulncheck":
		return setEnum(&o.Vulncheck, value,
			ModeVulncheckOff,
			ModeVulncheckImports)

	case "codelenses", "codelens":
		lensOverrides, err := asBoolMap[CodeLensSource](value)
		if err != nil {
			return err
		}
		if o.Codelenses == nil {
			o.Codelenses = make(map[CodeLensSource]bool)
		}
		o.Codelenses = maps.Clone(o.Codelenses)
		maps.Copy(o.Codelenses, lensOverrides)

		if name == "codelens" {
			return deprecatedError("codelenses")
		}

	case "staticcheck":
		return setBool(&o.Staticcheck, value)

	case "local":
		return setString(&o.Local, value)

	case "verboseOutput":
		return setBool(&o.VerboseOutput, value)

	case "verboseWorkDoneProgress":
		return setBool(&o.VerboseWorkDoneProgress, value)

	case "showBugReports":
		return setBool(&o.ShowBugReports, value)

	case "gofumpt":
		return setBool(&o.Gofumpt, value)

	case "completeFunctionCalls":
		return setBool(&o.CompleteFunctionCalls, value)

	case "semanticTokens":
		return setBool(&o.SemanticTokens, value)

	// TODO(hxjiang): deprecate noSemanticString and noSemanticNumber.
	case "noSemanticString":
		if err := setBool(&o.NoSemanticString, value); err != nil {
			return err
		}
		return &SoftError{fmt.Sprintf("noSemanticString setting is deprecated, use semanticTokenTypes instead (though you can continue to apply them for the time being).")}

	case "noSemanticNumber":
		if err := setBool(&o.NoSemanticNumber, value); err != nil {
			return nil
		}
		return &SoftError{fmt.Sprintf("noSemanticNumber setting is deprecated, use semanticTokenTypes instead (though you can continue to apply them for the time being).")}

	case "semanticTokenTypes":
		return setBoolMap(&o.SemanticTokenTypes, value)

	case "semanticTokenModifiers":
		return setBoolMap(&o.SemanticTokenModifiers, value)

	case "expandWorkspaceToModule":
		// See golang/go#63536: we can consider deprecating
		// expandWorkspaceToModule, but probably need to change the default
		// behavior in that case to *not* expand to the module.
		return setBool(&o.ExpandWorkspaceToModule, value)

	case "experimentalPostfixCompletions":
		return setBool(&o.ExperimentalPostfixCompletions, value)

	case "templateExtensions":
		switch value := value.(type) {
		case []any:
			return setStringSlice(&o.TemplateExtensions, value)
		case nil:
			o.TemplateExtensions = nil
		default:
			return fmt.Errorf("unexpected type %T (want JSON array of string)", value)
		}

	case "diagnosticsDelay":
		return setDuration(&o.DiagnosticsDelay, value)

	case "diagnosticsTrigger":
		return setEnum(&o.DiagnosticsTrigger, value,
			DiagnosticsOnEdit,
			DiagnosticsOnSave)

	case "analysisProgressReporting":
		return setBool(&o.AnalysisProgressReporting, value)

	case "allowImplicitNetworkAccess":
		return deprecatedError("")

	case "standaloneTags":
		return setStringSlice(&o.StandaloneTags, value)

	case "subdirWatchPatterns":
		return setEnum(&o.SubdirWatchPatterns, value,
			SubdirWatchPatternsOn,
			SubdirWatchPatternsOff,
			SubdirWatchPatternsAuto)

	case "reportAnalysisProgressAfter":
		return setDuration(&o.ReportAnalysisProgressAfter, value)

	case "telemetryPrompt":
		return setBool(&o.TelemetryPrompt, value)

	case "linkifyShowMessage":
		return setBool(&o.LinkifyShowMessage, value)

	case "includeReplaceInWorkspace":
		return setBool(&o.IncludeReplaceInWorkspace, value)

	case "zeroConfig":
		return setBool(&o.ZeroConfig, value)

	case "pullDiagnostics":
		return setBool(&o.PullDiagnostics, value)

	// deprecated and renamed settings
	//
	// These should never be deleted: there is essentially no cost
	// to providing a better error message indefinitely; it's not
	// as if we would ever want to recycle the name of a setting.

	// renamed
	case "experimentalDisabledAnalyses":
		return deprecatedError("analyses")

	case "disableDeepCompletion":
		return deprecatedError("deepCompletion")

	case "disableFuzzyMatching":
		return deprecatedError("fuzzyMatching")

	case "wantCompletionDocumentation":
		return deprecatedError("completionDocumentation")

	case "wantUnimportedCompletions":
		return deprecatedError("completeUnimported")

	case "fuzzyMatching":
		return deprecatedError("matcher")

	case "caseSensitiveCompletion":
		return deprecatedError("matcher")

	case "experimentalDiagnosticsDelay":
		return deprecatedError("diagnosticsDelay")

	// deprecated
	case "memoryMode":
		return deprecatedError("")

	case "tempModFile":
		return deprecatedError("")

	case "experimentalWorkspaceModule":
		return deprecatedError("")

	case "experimentalTemplateSupport":
		return deprecatedError("")

	case "experimentalWatchedFileDelay":
		return deprecatedError("")

	case "experimentalPackageCacheKey":
		return deprecatedError("")

	case "allowModfileModifications":
		return deprecatedError("")

	case "allExperiments":
		// golang/go#65548: this setting is a no-op, but we fail don't report it as
		// deprecated, since the nightly VS Code injects it.
		//
		// If, in the future, VS Code stops injecting this, we could theoretically
		// report an error here, but it also seems harmless to keep ignoring this
		// setting forever.

	case "experimentalUseInvalidMetadata":
		return deprecatedError("")

	case "newDiff":
		return deprecatedError("")

	case "wantSuggestedFixes":
		return deprecatedError("")

	case "noIncrementalSync":
		return deprecatedError("")

	case "watchFileChanges":
		return deprecatedError("")

	case "go-diff":
		return deprecatedError("")

	default:
		return fmt.Errorf("unexpected setting")
	}
	return nil
}

// EnabledSemanticTokenModifiers returns a map of modifiers to boolean.
func (o *Options) EnabledSemanticTokenModifiers() map[semtok.Modifier]bool {
	copy := make(map[semtok.Modifier]bool, len(o.SemanticTokenModifiers))
	for k, v := range o.SemanticTokenModifiers {
		copy[semtok.Modifier(k)] = v
	}
	return copy
}

// EncodeSemanticTokenTypes returns a map of types to boolean.
func (o *Options) EnabledSemanticTokenTypes() map[semtok.Type]bool {
	copy := make(map[semtok.Type]bool, len(o.SemanticTokenTypes))
	for k, v := range o.SemanticTokenModifiers {
		copy[semtok.Type(k)] = v
	}
	if o.NoSemanticString {
		copy[semtok.TokString] = false
	}
	if o.NoSemanticNumber {
		copy[semtok.TokNumber] = false
	}
	return copy
}

// A SoftError is an error that does not affect the functionality of gopls.
type SoftError struct {
	msg string
}

func (e *SoftError) Error() string {
	return e.msg
}

// softErrorf reports a soft error related to the current option.
func softErrorf(format string, args ...any) error {
	return &SoftError{fmt.Sprintf(format, args...)}
}

// deprecatedError reports the current setting as deprecated.
// The optional replacement is suggested to the user.
func deprecatedError(replacement string) error {
	msg := fmt.Sprintf("this setting is deprecated")
	if replacement != "" {
		msg = fmt.Sprintf("%s, use %q instead", msg, replacement)
	}
	return &SoftError{msg}
}

// setT() and asT() helpers: the setT forms write to the 'dest *T'
// variable only on success, to reduce boilerplate in Option.set.

func setBool(dest *bool, value any) error {
	b, err := asBool(value)
	if err != nil {
		return err
	}
	*dest = b
	return nil
}

func asBool(value any) (bool, error) {
	b, ok := value.(bool)
	if !ok {
		return false, fmt.Errorf("invalid type %T (want bool)", value)
	}
	return b, nil
}

func setDuration(dest *time.Duration, value any) error {
	str, err := asString(value)
	if err != nil {
		return err
	}
	parsed, err := time.ParseDuration(str)
	if err != nil {
		return err
	}
	*dest = parsed
	return nil
}

func setBoolMap[K ~string](dest *map[K]bool, value any) error {
	m, err := asBoolMap[K](value)
	if err != nil {
		return err
	}
	*dest = m
	return nil
}

func asBoolMap[K ~string](value any) (map[K]bool, error) {
	all, ok := value.(map[string]any)
	if !ok {
		return nil, fmt.Errorf("invalid type %T (want JSON object)", value)
	}
	m := make(map[K]bool)
	for a, enabled := range all {
		b, ok := enabled.(bool)
		if !ok {
			return nil, fmt.Errorf("invalid type %T for object field %q", enabled, a)
		}
		m[K(a)] = b
	}
	return m, nil
}

func setString(dest *string, value any) error {
	str, err := asString(value)
	if err != nil {
		return err
	}
	*dest = str
	return nil
}

func asString(value any) (string, error) {
	str, ok := value.(string)
	if !ok {
		return "", fmt.Errorf("invalid type %T (want string)", value)
	}
	return str, nil
}

func setStringSlice(dest *[]string, value any) error {
	slice, err := asStringSlice(value)
	if err != nil {
		return err
	}
	*dest = slice
	return nil
}

func asStringSlice(value any) ([]string, error) {
	array, ok := value.([]any)
	if !ok {
		return nil, fmt.Errorf("invalid type %T (want JSON array of string)", value)
	}
	var slice []string
	for _, elem := range array {
		str, ok := elem.(string)
		if !ok {
			return nil, fmt.Errorf("invalid array element type %T (want string)", elem)
		}
		slice = append(slice, str)
	}
	return slice, nil
}

func setEnum[S ~string](dest *S, value any, options ...S) error {
	enum, err := asEnum(value, options...)
	if err != nil {
		return err
	}
	*dest = enum
	return nil
}

func asEnum[S ~string](value any, options ...S) (S, error) {
	str, err := asString(value)
	if err != nil {
		return "", err
	}
	for _, opt := range options {
		if strings.EqualFold(str, string(opt)) {
			return opt, nil
		}
	}
	return "", fmt.Errorf("invalid option %q for enum", str)
}
