// 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 mod provides core features related to go.mod file
// handling for use by Go editors and tools.
package mod

import (
	"context"
	"fmt"
	"regexp"

	"golang.org/x/mod/modfile"
	"golang.org/x/tools/internal/lsp/debug/tag"
	"golang.org/x/tools/internal/lsp/protocol"
	"golang.org/x/tools/internal/lsp/source"
	"golang.org/x/tools/internal/telemetry/event"
)

func Diagnostics(ctx context.Context, snapshot source.Snapshot) (map[source.FileIdentity][]source.Diagnostic, map[string]*modfile.Require, error) {
	// TODO: We will want to support diagnostics for go.mod files even when the -modfile flag is turned off.
	realURI, tempURI := snapshot.View().ModFiles()

	// Check the case when the tempModfile flag is turned off.
	if realURI == "" || tempURI == "" {
		return nil, nil, nil
	}
	ctx, done := event.StartSpan(ctx, "mod.Diagnostics", tag.URI.Of(realURI))
	defer done()

	realfh, err := snapshot.GetFile(realURI)
	if err != nil {
		return nil, nil, err
	}
	mth, err := snapshot.ModTidyHandle(ctx, realfh)
	if err != nil {
		return nil, nil, err
	}
	_, _, missingDeps, parseErrors, err := mth.Tidy(ctx)
	if err != nil {
		return nil, nil, err
	}
	reports := map[source.FileIdentity][]source.Diagnostic{
		realfh.Identity(): {},
	}
	for _, e := range parseErrors {
		diag := source.Diagnostic{
			Message:        e.Message,
			Range:          e.Range,
			SuggestedFixes: e.SuggestedFixes,
			Source:         e.Category,
		}
		if e.Category == "syntax" {
			diag.Severity = protocol.SeverityError
		} else {
			diag.Severity = protocol.SeverityWarning
		}
		reports[realfh.Identity()] = append(reports[realfh.Identity()], diag)
	}
	return reports, missingDeps, nil
}

func SuggestedFixes(ctx context.Context, snapshot source.Snapshot, realfh source.FileHandle, diags []protocol.Diagnostic) []protocol.CodeAction {
	mth, err := snapshot.ModTidyHandle(ctx, realfh)
	if err != nil {
		return nil
	}
	_, _, _, parseErrors, err := mth.Tidy(ctx)
	if err != nil {
		return nil
	}

	errorsMap := make(map[string][]source.Error)
	for _, e := range parseErrors {
		if errorsMap[e.Message] == nil {
			errorsMap[e.Message] = []source.Error{}
		}
		errorsMap[e.Message] = append(errorsMap[e.Message], e)
	}

	var actions []protocol.CodeAction
	for _, diag := range diags {
		for _, e := range errorsMap[diag.Message] {
			if !sameDiagnostic(diag, e) {
				continue
			}
			for _, fix := range e.SuggestedFixes {
				action := protocol.CodeAction{
					Title:       fix.Title,
					Kind:        protocol.QuickFix,
					Diagnostics: []protocol.Diagnostic{diag},
					Edit:        protocol.WorkspaceEdit{},
				}
				for uri, edits := range fix.Edits {
					fh, err := snapshot.GetFile(uri)
					if err != nil {
						event.Error(ctx, "no file", err, tag.URI.Of(uri))
						continue
					}
					action.Edit.DocumentChanges = append(action.Edit.DocumentChanges, protocol.TextDocumentEdit{
						TextDocument: protocol.VersionedTextDocumentIdentifier{
							Version: fh.Identity().Version,
							TextDocumentIdentifier: protocol.TextDocumentIdentifier{
								URI: protocol.URIFromSpanURI(fh.Identity().URI),
							},
						},
						Edits: edits,
					})
				}
				actions = append(actions, action)
			}
		}
	}
	return actions
}

func SuggestedGoFixes(ctx context.Context, snapshot source.Snapshot, diags []protocol.Diagnostic) ([]protocol.CodeAction, error) {
	// TODO: We will want to support diagnostics for go.mod files even when the -modfile flag is turned off.
	realURI, tempURI := snapshot.View().ModFiles()

	// Check the case when the tempModfile flag is turned off.
	if realURI == "" || tempURI == "" {
		return nil, nil
	}

	ctx, done := event.StartSpan(ctx, "mod.SuggestedGoFixes", tag.URI.Of(realURI))
	defer done()

	realfh, err := snapshot.GetFile(realURI)
	if err != nil {
		return nil, err
	}
	mth, err := snapshot.ModTidyHandle(ctx, realfh)
	if err != nil {
		return nil, err
	}
	realFile, realMapper, missingDeps, _, err := mth.Tidy(ctx)
	if err != nil {
		return nil, err
	}
	// Get the contents of the go.mod file before we make any changes.
	oldContents, _, err := realfh.Read(ctx)
	if err != nil {
		return nil, err
	}

	var actions []protocol.CodeAction
	for _, diag := range diags {
		re := regexp.MustCompile(`(.+) is not in your go.mod file`)
		matches := re.FindStringSubmatch(diag.Message)
		if len(matches) != 2 {
			continue
		}
		req := missingDeps[matches[1]]
		if req == nil {
			continue
		}
		// Calculate the quick fix edits that need to be made to the go.mod file.
		if err := realFile.AddRequire(req.Mod.Path, req.Mod.Version); err != nil {
			return nil, err
		}
		realFile.Cleanup()
		newContents, err := realFile.Format()
		if err != nil {
			return nil, err
		}
		// Reset the *modfile.File back to before we added the dependency.
		if err := realFile.DropRequire(req.Mod.Path); err != nil {
			return nil, err
		}
		// Calculate the edits to be made due to the change.
		diff := snapshot.View().Options().ComputeEdits(realfh.Identity().URI, string(oldContents), string(newContents))
		edits, err := source.ToProtocolEdits(realMapper, diff)
		if err != nil {
			return nil, err
		}
		action := protocol.CodeAction{
			Title:       fmt.Sprintf("Add %s to go.mod", req.Mod.Path),
			Kind:        protocol.QuickFix,
			Diagnostics: []protocol.Diagnostic{diag},
			Edit: protocol.WorkspaceEdit{
				DocumentChanges: []protocol.TextDocumentEdit{
					{
						TextDocument: protocol.VersionedTextDocumentIdentifier{
							Version: realfh.Identity().Version,
							TextDocumentIdentifier: protocol.TextDocumentIdentifier{
								URI: protocol.URIFromSpanURI(realfh.Identity().URI),
							},
						},
						Edits: edits,
					},
				},
			},
		}
		actions = append(actions, action)
	}
	return actions, nil
}

func sameDiagnostic(d protocol.Diagnostic, e source.Error) bool {
	return d.Message == e.Message && protocol.CompareRange(d.Range, e.Range) == 0 && d.Source == e.Category
}
