// Copyright 2020 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 (
	"context"
	"fmt"
	"go/ast"
	"go/token"
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"golang.org/x/mod/modfile"
	"golang.org/x/tools/gopls/internal/lsp/command"
	"golang.org/x/tools/gopls/internal/lsp/protocol"
	"golang.org/x/tools/gopls/internal/lsp/source"
	"golang.org/x/tools/gopls/internal/span"
	"golang.org/x/tools/internal/event"
	"golang.org/x/tools/internal/event/tag"
	"golang.org/x/tools/internal/gocommand"
	"golang.org/x/tools/internal/memoize"
)

// ModTidy returns the go.mod file that would be obtained by running
// "go mod tidy". Concurrent requests are combined into a single command.
func (s *snapshot) ModTidy(ctx context.Context, pm *source.ParsedModule) (*source.TidiedModule, error) {
	uri := pm.URI
	if pm.File == nil {
		return nil, fmt.Errorf("cannot tidy unparseable go.mod file: %v", uri)
	}

	s.mu.Lock()
	entry, hit := s.modTidyHandles.Get(uri)
	s.mu.Unlock()

	type modTidyResult struct {
		tidied *source.TidiedModule
		err    error
	}

	// Cache miss?
	if !hit {
		// If the file handle is an overlay, it may not be written to disk.
		// The go.mod file has to be on disk for `go mod tidy` to work.
		// TODO(rfindley): is this still true with Go 1.16 overlay support?
		fh, err := s.GetFile(ctx, pm.URI)
		if err != nil {
			return nil, err
		}
		if _, ok := fh.(*overlay); ok {
			if info, _ := os.Stat(uri.Filename()); info == nil {
				return nil, source.ErrNoModOnDisk
			}
		}

		if criticalErr := s.GetCriticalError(ctx); criticalErr != nil {
			return &source.TidiedModule{
				Diagnostics: criticalErr.Diagnostics,
			}, nil
		}

		if err := s.awaitLoaded(ctx); err != nil {
			return nil, err
		}

		handle := memoize.NewPromise("modTidy", func(ctx context.Context, arg interface{}) interface{} {
			tidied, err := modTidyImpl(ctx, arg.(*snapshot), uri.Filename(), pm)
			return modTidyResult{tidied, err}
		})

		entry = handle
		s.mu.Lock()
		s.modTidyHandles.Set(uri, entry, nil)
		s.mu.Unlock()
	}

	// Await result.
	v, err := s.awaitPromise(ctx, entry.(*memoize.Promise))
	if err != nil {
		return nil, err
	}
	res := v.(modTidyResult)
	return res.tidied, res.err
}

// modTidyImpl runs "go mod tidy" on a go.mod file.
func modTidyImpl(ctx context.Context, snapshot *snapshot, filename string, pm *source.ParsedModule) (*source.TidiedModule, error) {
	ctx, done := event.Start(ctx, "cache.ModTidy", tag.URI.Of(filename))
	defer done()

	inv := &gocommand.Invocation{
		Verb:       "mod",
		Args:       []string{"tidy"},
		WorkingDir: filepath.Dir(filename),
	}
	// TODO(adonovan): ensure that unsaved overlays are passed through to 'go'.
	tmpURI, inv, cleanup, err := snapshot.goCommandInvocation(ctx, source.WriteTemporaryModFile, inv)
	if err != nil {
		return nil, err
	}
	// Keep the temporary go.mod file around long enough to parse it.
	defer cleanup()

	if _, err := snapshot.view.gocmdRunner.Run(ctx, *inv); err != nil {
		return nil, err
	}

	// Go directly to disk to get the temporary mod file,
	// since it is always on disk.
	tempContents, err := ioutil.ReadFile(tmpURI.Filename())
	if err != nil {
		return nil, err
	}
	ideal, err := modfile.Parse(tmpURI.Filename(), tempContents, nil)
	if err != nil {
		// We do not need to worry about the temporary file's parse errors
		// since it has been "tidied".
		return nil, err
	}

	// Compare the original and tidied go.mod files to compute errors and
	// suggested fixes.
	diagnostics, err := modTidyDiagnostics(ctx, snapshot, pm, ideal)
	if err != nil {
		return nil, err
	}

	return &source.TidiedModule{
		Diagnostics:   diagnostics,
		TidiedContent: tempContents,
	}, nil
}

// modTidyDiagnostics computes the differences between the original and tidied
// go.mod files to produce diagnostic and suggested fixes. Some diagnostics
// may appear on the Go files that import packages from missing modules.
func modTidyDiagnostics(ctx context.Context, snapshot *snapshot, pm *source.ParsedModule, ideal *modfile.File) (diagnostics []*source.Diagnostic, err error) {
	// First, determine which modules are unused and which are missing from the
	// original go.mod file.
	var (
		unused          = make(map[string]*modfile.Require, len(pm.File.Require))
		missing         = make(map[string]*modfile.Require, len(ideal.Require))
		wrongDirectness = make(map[string]*modfile.Require, len(pm.File.Require))
	)
	for _, req := range pm.File.Require {
		unused[req.Mod.Path] = req
	}
	for _, req := range ideal.Require {
		origReq := unused[req.Mod.Path]
		if origReq == nil {
			missing[req.Mod.Path] = req
			continue
		} else if origReq.Indirect != req.Indirect {
			wrongDirectness[req.Mod.Path] = origReq
		}
		delete(unused, req.Mod.Path)
	}
	for _, req := range wrongDirectness {
		// Handle dependencies that are incorrectly labeled indirect and
		// vice versa.
		srcDiag, err := directnessDiagnostic(pm.Mapper, req, snapshot.View().Options().ComputeEdits)
		if err != nil {
			// We're probably in a bad state if we can't compute a
			// directnessDiagnostic, but try to keep going so as to not suppress
			// other, valid diagnostics.
			event.Error(ctx, "computing directness diagnostic", err)
			continue
		}
		diagnostics = append(diagnostics, srcDiag)
	}
	// Next, compute any diagnostics for modules that are missing from the
	// go.mod file. The fixes will be for the go.mod file, but the
	// diagnostics should also appear in both the go.mod file and the import
	// statements in the Go files in which the dependencies are used.
	missingModuleFixes := map[*modfile.Require][]source.SuggestedFix{}
	for _, req := range missing {
		srcDiag, err := missingModuleDiagnostic(pm, req)
		if err != nil {
			return nil, err
		}
		missingModuleFixes[req] = srcDiag.SuggestedFixes
		diagnostics = append(diagnostics, srcDiag)
	}
	// Add diagnostics for missing modules anywhere they are imported in the
	// workspace.
	// TODO(adonovan): opt: opportunities for parallelism abound.
	for _, id := range snapshot.workspacePackageIDs() {
		m := snapshot.getMetadata(id)
		if m == nil {
			return nil, fmt.Errorf("no metadata for %s", id)
		}

		// Read both lists of files of this package, in parallel.
		goFiles, compiledGoFiles, err := readGoFiles(ctx, snapshot, m)
		if err != nil {
			return nil, err
		}

		missingImports := map[string]*modfile.Require{}

		// If -mod=readonly is not set we may have successfully imported
		// packages from missing modules. Otherwise they'll be in
		// MissingDependencies. Combine both.
		for imp := range parseImports(ctx, snapshot, goFiles) {
			if req, ok := missing[imp]; ok {
				missingImports[imp] = req
				break
			}
			// If the import is a package of the dependency, then add the
			// package to the map, this will eliminate the need to do this
			// prefix package search on each import for each file.
			// Example:
			//
			// import (
			//   "golang.org/x/tools/go/expect"
			//   "golang.org/x/tools/go/packages"
			// )
			// They both are related to the same module: "golang.org/x/tools".
			var match string
			for _, req := range ideal.Require {
				if strings.HasPrefix(imp, req.Mod.Path) && len(req.Mod.Path) > len(match) {
					match = req.Mod.Path
				}
			}
			if req, ok := missing[match]; ok {
				missingImports[imp] = req
			}
		}
		// None of this package's imports are from missing modules.
		if len(missingImports) == 0 {
			continue
		}
		for _, goFile := range compiledGoFiles {
			pgf, err := snapshot.ParseGo(ctx, goFile, source.ParseHeader)
			if err != nil {
				continue
			}
			file, m := pgf.File, pgf.Mapper
			if file == nil || m == nil {
				continue
			}
			imports := make(map[string]*ast.ImportSpec)
			for _, imp := range file.Imports {
				if imp.Path == nil {
					continue
				}
				if target, err := strconv.Unquote(imp.Path.Value); err == nil {
					imports[target] = imp
				}
			}
			if len(imports) == 0 {
				continue
			}
			for importPath, req := range missingImports {
				imp, ok := imports[importPath]
				if !ok {
					continue
				}
				fixes, ok := missingModuleFixes[req]
				if !ok {
					return nil, fmt.Errorf("no missing module fix for %q (%q)", importPath, req.Mod.Path)
				}
				srcErr, err := missingModuleForImport(pgf.Tok, m, imp, req, fixes)
				if err != nil {
					return nil, err
				}
				diagnostics = append(diagnostics, srcErr)
			}
		}
	}
	// Finally, add errors for any unused dependencies.
	onlyDiagnostic := len(diagnostics) == 0 && len(unused) == 1
	for _, req := range unused {
		srcErr, err := unusedDiagnostic(pm.Mapper, req, onlyDiagnostic)
		if err != nil {
			return nil, err
		}
		diagnostics = append(diagnostics, srcErr)
	}
	return diagnostics, nil
}

// unusedDiagnostic returns a source.Diagnostic for an unused require.
func unusedDiagnostic(m *protocol.ColumnMapper, req *modfile.Require, onlyDiagnostic bool) (*source.Diagnostic, error) {
	rng, err := m.OffsetRange(req.Syntax.Start.Byte, req.Syntax.End.Byte)
	if err != nil {
		return nil, err
	}
	title := fmt.Sprintf("Remove dependency: %s", req.Mod.Path)
	cmd, err := command.NewRemoveDependencyCommand(title, command.RemoveDependencyArgs{
		URI:            protocol.URIFromSpanURI(m.URI),
		OnlyDiagnostic: onlyDiagnostic,
		ModulePath:     req.Mod.Path,
	})
	if err != nil {
		return nil, err
	}
	return &source.Diagnostic{
		URI:            m.URI,
		Range:          rng,
		Severity:       protocol.SeverityWarning,
		Source:         source.ModTidyError,
		Message:        fmt.Sprintf("%s is not used in this module", req.Mod.Path),
		SuggestedFixes: []source.SuggestedFix{source.SuggestedFixFromCommand(cmd, protocol.QuickFix)},
	}, nil
}

// directnessDiagnostic extracts errors when a dependency is labeled indirect when
// it should be direct and vice versa.
func directnessDiagnostic(m *protocol.ColumnMapper, req *modfile.Require, computeEdits source.DiffFunction) (*source.Diagnostic, error) {
	rng, err := m.OffsetRange(req.Syntax.Start.Byte, req.Syntax.End.Byte)
	if err != nil {
		return nil, err
	}
	direction := "indirect"
	if req.Indirect {
		direction = "direct"

		// If the dependency should be direct, just highlight the // indirect.
		if comments := req.Syntax.Comment(); comments != nil && len(comments.Suffix) > 0 {
			end := comments.Suffix[0].Start
			end.LineRune += len(comments.Suffix[0].Token)
			end.Byte += len(comments.Suffix[0].Token)
			rng, err = m.OffsetRange(comments.Suffix[0].Start.Byte, end.Byte)
			if err != nil {
				return nil, err
			}
		}
	}
	// If the dependency should be indirect, add the // indirect.
	edits, err := switchDirectness(req, m, computeEdits)
	if err != nil {
		return nil, err
	}
	return &source.Diagnostic{
		URI:      m.URI,
		Range:    rng,
		Severity: protocol.SeverityWarning,
		Source:   source.ModTidyError,
		Message:  fmt.Sprintf("%s should be %s", req.Mod.Path, direction),
		SuggestedFixes: []source.SuggestedFix{{
			Title: fmt.Sprintf("Change %s to %s", req.Mod.Path, direction),
			Edits: map[span.URI][]protocol.TextEdit{
				m.URI: edits,
			},
			ActionKind: protocol.QuickFix,
		}},
	}, nil
}

func missingModuleDiagnostic(pm *source.ParsedModule, req *modfile.Require) (*source.Diagnostic, error) {
	var rng protocol.Range
	// Default to the start of the file if there is no module declaration.
	if pm.File != nil && pm.File.Module != nil && pm.File.Module.Syntax != nil {
		start, end := pm.File.Module.Syntax.Span()
		var err error
		rng, err = pm.Mapper.OffsetRange(start.Byte, end.Byte)
		if err != nil {
			return nil, err
		}
	}
	title := fmt.Sprintf("Add %s to your go.mod file", req.Mod.Path)
	cmd, err := command.NewAddDependencyCommand(title, command.DependencyArgs{
		URI:        protocol.URIFromSpanURI(pm.Mapper.URI),
		AddRequire: !req.Indirect,
		GoCmdArgs:  []string{req.Mod.Path + "@" + req.Mod.Version},
	})
	if err != nil {
		return nil, err
	}
	return &source.Diagnostic{
		URI:            pm.Mapper.URI,
		Range:          rng,
		Severity:       protocol.SeverityError,
		Source:         source.ModTidyError,
		Message:        fmt.Sprintf("%s is not in your go.mod file", req.Mod.Path),
		SuggestedFixes: []source.SuggestedFix{source.SuggestedFixFromCommand(cmd, protocol.QuickFix)},
	}, nil
}

// switchDirectness gets the edits needed to change an indirect dependency to
// direct and vice versa.
func switchDirectness(req *modfile.Require, m *protocol.ColumnMapper, computeEdits source.DiffFunction) ([]protocol.TextEdit, error) {
	// We need a private copy of the parsed go.mod file, since we're going to
	// modify it.
	copied, err := modfile.Parse("", m.Content, nil)
	if err != nil {
		return nil, err
	}
	// Change the directness in the matching require statement. To avoid
	// reordering the require statements, rewrite all of them.
	var requires []*modfile.Require
	seenVersions := make(map[string]string)
	for _, r := range copied.Require {
		if seen := seenVersions[r.Mod.Path]; seen != "" && seen != r.Mod.Version {
			// Avoid a panic in SetRequire below, which panics on conflicting
			// versions.
			return nil, fmt.Errorf("%q has conflicting versions: %q and %q", r.Mod.Path, seen, r.Mod.Version)
		}
		seenVersions[r.Mod.Path] = r.Mod.Version
		if r.Mod.Path == req.Mod.Path {
			requires = append(requires, &modfile.Require{
				Mod:      r.Mod,
				Syntax:   r.Syntax,
				Indirect: !r.Indirect,
			})
			continue
		}
		requires = append(requires, r)
	}
	copied.SetRequire(requires)
	newContent, err := copied.Format()
	if err != nil {
		return nil, err
	}
	// Calculate the edits to be made due to the change.
	edits := computeEdits(string(m.Content), string(newContent))
	return source.ToProtocolEdits(m, edits)
}

// missingModuleForImport creates an error for a given import path that comes
// from a missing module.
func missingModuleForImport(file *token.File, m *protocol.ColumnMapper, imp *ast.ImportSpec, req *modfile.Require, fixes []source.SuggestedFix) (*source.Diagnostic, error) {
	if req.Syntax == nil {
		return nil, fmt.Errorf("no syntax for %v", req)
	}
	rng, err := m.PosRange(imp.Path.Pos(), imp.Path.End())
	if err != nil {
		return nil, err
	}
	return &source.Diagnostic{
		URI:            m.URI,
		Range:          rng,
		Severity:       protocol.SeverityError,
		Source:         source.ModTidyError,
		Message:        fmt.Sprintf("%s is not in your go.mod file", req.Mod.Path),
		SuggestedFixes: fixes,
	}, nil
}

func spanFromPositions(m *protocol.ColumnMapper, s, e modfile.Position) (span.Span, error) {
	toPoint := func(offset int) (span.Point, error) {
		l, c, err := span.ToPosition(m.TokFile, offset)
		if err != nil {
			return span.Point{}, err
		}
		return span.NewPoint(l, c, offset), nil
	}
	start, err := toPoint(s.Byte)
	if err != nil {
		return span.Span{}, err
	}
	end, err := toPoint(e.Byte)
	if err != nil {
		return span.Span{}, err
	}
	return span.New(m.URI, start, end), nil
}

// parseImports parses the headers of the specified files and returns
// the set of strings that appear in import declarations within
// GoFiles. Errors are ignored.
//
// (We can't simply use Metadata.Imports because it is based on
// CompiledGoFiles, after cgo processing.)
func parseImports(ctx context.Context, s *snapshot, files []source.FileHandle) map[string]bool {
	s.mu.Lock() // peekOrParse requires a locked snapshot (!)
	defer s.mu.Unlock()
	seen := make(map[string]bool)
	for _, file := range files {
		f, err := peekOrParse(ctx, s, file, source.ParseHeader)
		if err != nil {
			continue
		}
		for _, spec := range f.File.Imports {
			path, _ := strconv.Unquote(spec.Path.Value)
			seen[path] = true
		}
	}
	return seen
}
