// Copyright 2023 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 cache

import (
	"encoding/json"
	"fmt"

	"golang.org/x/tools/gopls/internal/protocol"
	"golang.org/x/tools/gopls/internal/util/bug"
)

// A InitializationError is an error that causes snapshot initialization to fail.
// It is either the error returned from go/packages.Load, or an error parsing a
// workspace go.work or go.mod file.
//
// Such an error generally indicates that the View is malformed, and will never
// be usable.
type InitializationError struct {
	// MainError is the primary error. Must be non-nil.
	MainError error

	// Diagnostics contains any supplemental (structured) diagnostics extracted
	// from the load error.
	Diagnostics map[protocol.DocumentURI][]*Diagnostic
}

func byURI(d *Diagnostic) protocol.DocumentURI { return d.URI } // For use in maps.Group.

// An Diagnostic corresponds to an LSP Diagnostic.
// https://microsoft.github.io/language-server-protocol/specification#diagnostic
//
// It is (effectively) gob-serializable; see {encode,decode}Diagnostics.
type Diagnostic struct {
	URI      protocol.DocumentURI // of diagnosed file (not diagnostic documentation)
	Range    protocol.Range
	Severity protocol.DiagnosticSeverity
	Code     string // analysis.Diagnostic.Category (or "default" if empty) or hidden go/types error code
	CodeHref string

	// Source is a human-readable description of the source of the error.
	// Diagnostics generated by an analysis.Analyzer set it to Analyzer.Name.
	Source DiagnosticSource

	Message string

	Tags    []protocol.DiagnosticTag
	Related []protocol.DiagnosticRelatedInformation

	// Fields below are used internally to generate lazy fixes. They aren't
	// part of the LSP spec and historically didn't leave the server.
	//
	// Update(2023-05): version 3.16 of the LSP spec included support for the
	// Diagnostic.data field, which holds arbitrary data preserved in the
	// diagnostic for codeAction requests. This field allows bundling additional
	// information for lazy fixes, and gopls can (and should) use this
	// information to avoid re-evaluating diagnostics in code-action handlers.
	//
	// In order to stage this transition incrementally, the 'BundledFixes' field
	// may store a 'bundled' (=json-serialized) form of the associated
	// SuggestedFixes. Not all diagnostics have their fixes bundled.
	BundledFixes   *json.RawMessage
	SuggestedFixes []SuggestedFix
}

func (d *Diagnostic) String() string {
	return fmt.Sprintf("%v: %s", d.Range, d.Message)
}

type DiagnosticSource string

const (
	UnknownError             DiagnosticSource = "<Unknown source>"
	ListError                DiagnosticSource = "go list"
	ParseError               DiagnosticSource = "syntax"
	TypeError                DiagnosticSource = "compiler"
	ModTidyError             DiagnosticSource = "go mod tidy"
	OptimizationDetailsError DiagnosticSource = "optimizer details"
	UpgradeNotification      DiagnosticSource = "upgrade available"
	Vulncheck                DiagnosticSource = "vulncheck imports"
	Govulncheck              DiagnosticSource = "govulncheck"
	TemplateError            DiagnosticSource = "template"
	WorkFileError            DiagnosticSource = "go.work file"
	ConsistencyInfo          DiagnosticSource = "consistency"
)

// A SuggestedFix represents a suggested fix (for a diagnostic)
// produced by analysis, in protocol form.
//
// The fixes are reported to the client as a set of code actions in
// response to a CodeAction query for a set of diagnostics. Multiple
// SuggestedFixes may be produced for the same logical fix, varying
// only in ActionKind. For example, a fix may be both a Refactor
// (which should appear on the refactoring menu) and a SourceFixAll (a
// clear fix that can be safely applied without explicit consent).
type SuggestedFix struct {
	Title      string
	Edits      map[protocol.DocumentURI][]protocol.TextEdit
	Command    *protocol.Command
	ActionKind protocol.CodeActionKind
}

// SuggestedFixFromCommand returns a suggested fix to run the given command.
func SuggestedFixFromCommand(cmd protocol.Command, kind protocol.CodeActionKind) SuggestedFix {
	return SuggestedFix{
		Title:      cmd.Title,
		Command:    &cmd,
		ActionKind: kind,
	}
}

// lazyFixesJSON is a JSON-serializable list of code actions (arising
// from "lazy" SuggestedFixes with no Edits) to be saved in the
// protocol.Diagnostic.Data field. Computation of the edits is thus
// deferred until the action's command is invoked.
type lazyFixesJSON struct {
	// TODO(rfindley): pack some sort of identifier here for later
	// lookup/validation?
	Actions []protocol.CodeAction
}

// bundleLazyFixes attempts to bundle sd.SuggestedFixes into the
// sd.BundledFixes field, so that it can be round-tripped through the client.
// It returns false if the fixes cannot be bundled.
func bundleLazyFixes(sd *Diagnostic) bool {
	if len(sd.SuggestedFixes) == 0 {
		return true
	}
	var actions []protocol.CodeAction
	for _, fix := range sd.SuggestedFixes {
		if fix.Edits != nil {
			// For now, we only support bundled code actions that execute commands.
			//
			// In order to cleanly support bundled edits, we'd have to guarantee that
			// the edits were generated on the current snapshot. But this naively
			// implies that every fix would have to include a snapshot ID, which
			// would require us to republish all diagnostics on each new snapshot.
			//
			// TODO(rfindley): in order to avoid this additional chatter, we'd need
			// to build some sort of registry or other mechanism on the snapshot to
			// check whether a diagnostic is still valid.
			return false
		}
		action := protocol.CodeAction{
			Title:   fix.Title,
			Kind:    fix.ActionKind,
			Command: fix.Command,
		}
		actions = append(actions, action)
	}
	fixes := lazyFixesJSON{
		Actions: actions,
	}
	data, err := json.Marshal(fixes)
	if err != nil {
		bug.Reportf("marshalling lazy fixes: %v", err)
		return false
	}
	msg := json.RawMessage(data)
	sd.BundledFixes = &msg
	return true
}

// BundledLazyFixes extracts any bundled codeActions from the
// diag.Data field.
func BundledLazyFixes(diag protocol.Diagnostic) []protocol.CodeAction {
	var fix lazyFixesJSON
	if diag.Data != nil {
		err := protocol.UnmarshalJSON(*diag.Data, &fix)
		if err != nil {
			bug.Reportf("unmarshalling lazy fix: %v", err)
			return nil
		}
	}

	var actions []protocol.CodeAction
	for _, action := range fix.Actions {
		// See bundleLazyFixes: for now we only support bundling commands.
		if action.Edit != nil {
			bug.Reportf("bundled fix %q includes workspace edits", action.Title)
			continue
		}
		// associate the action with the incoming diagnostic
		// (Note that this does not mutate the fix.Fixes slice).
		action.Diagnostics = []protocol.Diagnostic{diag}
		actions = append(actions, action)
	}

	return actions
}
