// 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/util/frob"
)

type Annotation string

const (
	// Nil controls nil checks.
	Nil Annotation = "nil"

	// Escape controls diagnostics about escape choices.
	Escape Annotation = "escape"

	// Inline controls diagnostics about inlining choices.
	Inline Annotation = "inline"

	// Bounds controls bounds checking diagnostics.
	Bounds Annotation = "bounds"
)

// 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
	SemanticTypes                              []string
	SemanticMods                               []string
	RelatedInformationSupported                bool
	CompletionTags                             bool
	CompletionDeprecated                       bool
	SupportedResourceOperations                []protocol.ResourceOperationKind
	CodeActionResolveOptions                   []string
}

// 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
}

// 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.
	//     "gc_details": true  // Show a code lens toggling the display of gc's choices.
	//   }
	// ...
	// }
	// ```
	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'
	NoSemanticString bool `status:"experimental"`

	// NoSemanticNumber  turns off the sending of the semantic token 'number'
	NoSemanticNumber 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 (
	// Toggle display of Go compiler optimization decisions
	//
	// This codelens source causes the `package` declaration of
	// each file to be annotated with a command to toggle the
	// state of the per-session variable that controls whether
	// optimization decisions from the Go compiler (formerly known
	// as "gc") should be displayed as diagnostics.
	//
	// Optimization decisions include:
	// - whether a variable escapes, and how escape is inferred;
	// - whether a nil-pointer check is implied or eliminated;
	// - whether a function can be inlined.
	//
	// TODO(adonovan): this source is off by default because the
	// annotation is annoying and because VS Code has a separate
	// "Toggle gc details" command. Replace it with a Code Action
	// ("Source action...").
	CodeLensGCDetails CodeLensSource = "gc_details"

	// 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.
	//
	// [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 and Structured are 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"`

	// Annotations specifies the various kinds of optimization diagnostics
	// that should be reported by the gc_details command.
	Annotations map[Annotation]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

	// AddTestSourceCodeAction enables support for adding test as a source code
	// action.
	// TODO(hxjiang): remove this option once the feature is implemented.
	AddTestSourceCodeAction 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
}

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"

	// Structured is an experimental setting that returns a structured hover format.
	// This format separates the signature from the documentation, so that the client
	// can do more manipulation of these fields.
	//
	// This should only be used by clients that support this behavior.
	Structured HoverKind = "Structured"
)

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
	// 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 "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 "addTestSourceCodeAction":
		return setBool(&o.AddTestSourceCodeAction, value)
	case "completionBudget":
		return setDuration(&o.CompletionBudget, value)
	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":
		return setEnum(&o.HoverKind, value,
			NoDocumentation,
			SingleLine,
			SynopsisDocumentation,
			FullDocumentation,
			Structured)

	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 setAnnotationMap(&o.Annotations, value)

	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)
		for source, enabled := range lensOverrides {
			o.Codelenses[source] = enabled
		}

		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)

	case "noSemanticString":
		return setBool(&o.NoSemanticString, value)

	case "noSemanticNumber":
		return setBool(&o.NoSemanticNumber, 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
}

// 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 setAnnotationMap(dest *map[Annotation]bool, value any) error {
	all, err := asBoolMap[string](value)
	if err != nil {
		return err
	}
	if all == nil {
		return nil
	}
	// Default to everything enabled by default.
	m := make(map[Annotation]bool)
	for k, enabled := range all {
		var a Annotation
		if err := setEnum(&a, k,
			Nil,
			Escape,
			Inline,
			Bounds); err != nil {
			// In case of an error, process any legacy values.
			switch k {
			case "noEscape":
				m[Escape] = false
				return fmt.Errorf(`"noEscape" is deprecated, set "Escape: false" instead`)
			case "noNilcheck":
				m[Nil] = false
				return fmt.Errorf(`"noNilcheck" is deprecated, set "Nil: false" instead`)

			case "noInline":
				m[Inline] = false
				return fmt.Errorf(`"noInline" is deprecated, set "Inline: false" instead`)
			case "noBounds":
				m[Bounds] = false
				return fmt.Errorf(`"noBounds" is deprecated, set "Bounds: false" instead`)
			default:
				return err
			}
		}
		m[a] = enabled
	}
	*dest = m
	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)
}
