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

import (
	"context"
	"flag"
	"fmt"

	"golang.org/x/tools/gopls/internal/lsp/protocol"
	"golang.org/x/tools/gopls/internal/util/slices"
	"golang.org/x/tools/internal/tool"
)

// TODO(adonovan): this command has a very poor user interface. It
// should have a way to query the available fixes for a file (without
// a span), enumerate the valid fix kinds, enable all fixes, and not
// require the pointless -all flag. See issue #60290.

// suggestedFix implements the fix verb for gopls.
type suggestedFix struct {
	EditFlags
	All bool `flag:"a,all" help:"apply all fixes, not just preferred fixes"`

	app *Application
}

func (s *suggestedFix) Name() string      { return "fix" }
func (s *suggestedFix) Parent() string    { return s.app.Name() }
func (s *suggestedFix) Usage() string     { return "[fix-flags] <filename>" }
func (s *suggestedFix) ShortHelp() string { return "apply suggested fixes" }
func (s *suggestedFix) DetailedHelp(f *flag.FlagSet) {
	fmt.Fprintf(f.Output(), `
Example: apply fixes to this file, rewriting it:

	$ gopls fix -a -w internal/cmd/check.go

The -a (-all) flag causes all fixes, not just preferred ones, to be
applied, but since no fixes are currently preferred, this flag is
essentially mandatory.

Arguments after the filename are interpreted as LSP CodeAction kinds
to be applied; the default set is {"quickfix"}, but valid kinds include:

	quickfix
	refactor
	refactor.extract
	refactor.inline
	refactor.rewrite
	source.organizeImports
	source.fixAll

CodeAction kinds are hierarchical, so "refactor" includes
"refactor.inline". There is currently no way to enable or even
enumerate all kinds.

Example: apply any "refactor.rewrite" fixes at the specific byte
offset within this file:

	$ gopls fix -a internal/cmd/check.go:#43 refactor.rewrite

fix-flags:
`)
	printFlagDefaults(f)
}

// Run performs diagnostic checks on the file specified and either;
// - if -w is specified, updates the file in place;
// - if -d is specified, prints out unified diffs of the changes; or
// - otherwise, prints the new versions to stdout.
func (s *suggestedFix) Run(ctx context.Context, args ...string) error {
	if len(args) < 1 {
		return tool.CommandLineErrorf("fix expects at least 1 argument")
	}
	s.app.editFlags = &s.EditFlags
	conn, err := s.app.connect(ctx, nil)
	if err != nil {
		return err
	}
	defer conn.terminate(ctx)

	from := parseSpan(args[0])
	uri := from.URI()
	file, err := conn.openFile(ctx, uri)
	if err != nil {
		return err
	}
	rng, err := file.spanRange(from)
	if err != nil {
		return err
	}

	// Get diagnostics.
	if err := conn.diagnoseFiles(ctx, []protocol.DocumentURI{uri}); err != nil {
		return err
	}
	diagnostics := []protocol.Diagnostic{} // LSP wants non-nil slice
	conn.client.filesMu.Lock()
	diagnostics = append(diagnostics, file.diagnostics...)
	conn.client.filesMu.Unlock()

	// Request code actions
	codeActionKinds := []protocol.CodeActionKind{protocol.QuickFix}
	if len(args) > 1 {
		codeActionKinds = []protocol.CodeActionKind{}
		for _, k := range args[1:] {
			codeActionKinds = append(codeActionKinds, protocol.CodeActionKind(k))
		}
	}
	p := protocol.CodeActionParams{
		TextDocument: protocol.TextDocumentIdentifier{
			URI: uri,
		},
		Context: protocol.CodeActionContext{
			Only:        codeActionKinds,
			Diagnostics: diagnostics,
		},
		Range: rng,
	}
	actions, err := conn.CodeAction(ctx, &p)
	if err != nil {
		return fmt.Errorf("%v: %v", from, err)
	}

	// Gather edits from matching code actions.
	var edits []protocol.TextEdit
	for _, a := range actions {
		// Without -all, apply only "preferred" fixes.
		if !a.IsPreferred && !s.All {
			continue
		}

		// Execute any command.
		// This may cause the server to make
		// an ApplyEdit downcall to the client.
		if a.Command != nil {
			if _, err := conn.ExecuteCommand(ctx, &protocol.ExecuteCommandParams{
				Command:   a.Command.Command,
				Arguments: a.Command.Arguments,
			}); err != nil {
				return err
			}
			// The specification says that commands should
			// be executed _after_ edits are applied, not
			// instead of them, but we don't want to
			// duplicate edits.
			continue
		}

		// If the provided span has a position (not just offsets),
		// and the action has diagnostics, the action must have a
		// diagnostic with the same range as it.
		if from.HasPosition() && len(a.Diagnostics) > 0 &&
			!slices.ContainsFunc(a.Diagnostics, func(diag protocol.Diagnostic) bool {
				return diag.Range.Start == rng.Start
			}) {
			continue
		}

		// Partially apply CodeAction.Edit, a WorkspaceEdit.
		// (See also conn.Client.applyWorkspaceEdit(a.Edit)).
		for _, c := range a.Edit.DocumentChanges {
			tde := c.TextDocumentEdit
			if tde != nil && tde.TextDocument.URI == uri {
				edits = append(edits, protocol.AsTextEdits(tde.Edits)...)
			}
		}
	}

	return applyTextEdits(file.mapper, edits, s.app.editFlags)
}
