// Copyright 2018 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 source

import (
	"context"
	"fmt"
	"go/ast"
	"path/filepath"
	"strconv"
	"strings"

	"golang.org/x/mod/modfile"
	"golang.org/x/tools/go/analysis"
	"golang.org/x/tools/internal/event"
	"golang.org/x/tools/internal/lsp/debug/tag"
	"golang.org/x/tools/internal/lsp/protocol"
	"golang.org/x/tools/internal/span"
	errors "golang.org/x/xerrors"
)

type Diagnostic struct {
	Range    protocol.Range
	Message  string
	Source   string
	Severity protocol.DiagnosticSeverity
	Tags     []protocol.DiagnosticTag

	Related []RelatedInformation
}

type SuggestedFix struct {
	Title string
	Edits map[span.URI][]protocol.TextEdit
}

type RelatedInformation struct {
	URI     span.URI
	Range   protocol.Range
	Message string
}

func Diagnostics(ctx context.Context, snapshot Snapshot, ph PackageHandle, missingModules map[string]*modfile.Require, withAnalysis bool) (map[FileIdentity][]*Diagnostic, bool, error) {
	onlyIgnoredFiles := true
	for _, pgh := range ph.CompiledGoFiles() {
		onlyIgnoredFiles = onlyIgnoredFiles && ignoreFile(pgh.File().URI().Filename())
	}
	if onlyIgnoredFiles {
		return nil, false, nil
	}

	// If we are missing dependencies, it may because the user's workspace is
	// not correctly configured. Report errors, if possible.
	var warn bool
	if len(ph.MissingDependencies()) > 0 {
		warn = true
	}
	pkg, err := ph.Check(ctx)
	if err != nil {
		return nil, false, err
	}
	// If we have a package with a single file and errors about "undeclared" symbols,
	// we may have an ad-hoc package with multiple files. Show a warning message.
	// TODO(golang/go#36416): Remove this when golang.org/cl/202277 is merged.
	if len(pkg.CompiledGoFiles()) == 1 && hasUndeclaredErrors(pkg) {
		warn = true
	}

	missing := make(map[string]*modfile.Require)
	for _, imp := range pkg.Imports() {
		if req, ok := missingModules[imp.PkgPath()]; ok {
			missing[imp.PkgPath()] = req
			continue
		}
		for dep, req := range missingModules {
			// 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"
			if req != nil && strings.HasPrefix(imp.PkgPath(), dep) {
				missing[imp.PkgPath()] = req
				break
			}
		}
	}

	// Prepare the reports we will send for the files in this package.
	reports := make(map[FileIdentity][]*Diagnostic)
	for _, pgh := range pkg.CompiledGoFiles() {
		clearReports(ctx, snapshot, reports, pgh.File().URI())
		if len(missing) > 0 {
			if err := missingModulesDiagnostics(ctx, snapshot, reports, missing, pgh.File().URI()); err != nil {
				return nil, warn, err
			}
		}
	}
	// Prepare any additional reports for the errors in this package.
	for _, e := range pkg.GetErrors() {
		// We only need to handle lower-level errors.
		if e.Kind != ListError {
			continue
		}
		// If no file is associated with the error, pick an open file from the package.
		if e.URI.Filename() == "" {
			for _, pgh := range pkg.CompiledGoFiles() {
				if snapshot.IsOpen(pgh.File().URI()) {
					e.URI = pgh.File().URI()
				}
			}
		}
		clearReports(ctx, snapshot, reports, e.URI)
	}
	// Run diagnostics for the package that this URI belongs to.
	hadDiagnostics, hadTypeErrors, err := diagnostics(ctx, snapshot, reports, pkg, len(ph.MissingDependencies()) > 0)
	if err != nil {
		return nil, warn, err
	}
	if hadDiagnostics || !withAnalysis {
		return reports, warn, nil
	}
	// Exit early if the context has been canceled. This also protects us
	// from a race on Options, see golang/go#36699.
	if ctx.Err() != nil {
		return nil, warn, ctx.Err()
	}
	// If we don't have any list or parse errors, run analyses.
	analyzers := pickAnalyzers(snapshot, hadTypeErrors)
	if err := analyses(ctx, snapshot, reports, ph, analyzers); err != nil {
		event.Error(ctx, "analyses failed", err, tag.Snapshot.Of(snapshot.ID()), tag.Package.Of(ph.ID()))
		if ctx.Err() != nil {
			return nil, warn, ctx.Err()
		}
	}
	return reports, warn, nil
}

// ignoreFile is an approximation of go list's exclusion rules. go help list:
// 		Directory and file names that begin with "." or "_" are ignored
// 		by the go tool, as are directories named "testdata".
// Those rules only apply if the directory in question is beneath GOPATH
// or the module root, but we don't really have that information, so we just
// hope that nobody's messing with us.
func ignoreFile(path string) bool {
	for _, component := range strings.Split(path, string(filepath.Separator)) {
		if len(component) == 0 {
			continue
		}
		if component[0] == '.' || component[0] == '_' || component == "testdata" {
			return true
		}
	}
	return false
}

func pickAnalyzers(snapshot Snapshot, hadTypeErrors bool) map[string]Analyzer {
	analyzers := make(map[string]Analyzer)

	// Always run convenience analyzers.
	for k, v := range snapshot.View().Options().ConvenienceAnalyzers {
		analyzers[k] = v
	}
	// If we had type errors, only run type error analyzers.
	if hadTypeErrors {
		for k, v := range snapshot.View().Options().TypeErrorAnalyzers {
			analyzers[k] = v
		}
		return analyzers
	}
	for k, v := range snapshot.View().Options().DefaultAnalyzers {
		analyzers[k] = v
	}
	return analyzers
}

func FileDiagnostics(ctx context.Context, snapshot Snapshot, uri span.URI) (FileIdentity, []*Diagnostic, error) {
	fh, err := snapshot.GetFile(ctx, uri)
	if err != nil {
		return FileIdentity{}, nil, err
	}
	phs, err := snapshot.PackageHandles(ctx, fh)
	if err != nil {
		return FileIdentity{}, nil, err
	}
	ph, err := NarrowestPackageHandle(phs)
	if err != nil {
		return FileIdentity{}, nil, err
	}
	reports, _, err := Diagnostics(ctx, snapshot, ph, nil, true)
	if err != nil {
		return FileIdentity{}, nil, err
	}
	diagnostics, ok := reports[fh.Identity()]
	if !ok {
		return FileIdentity{}, nil, errors.Errorf("no diagnostics for %s", uri)
	}
	return fh.Identity(), diagnostics, nil
}

type diagnosticSet struct {
	listErrors, parseErrors, typeErrors []*Diagnostic
}

func diagnostics(ctx context.Context, snapshot Snapshot, reports map[FileIdentity][]*Diagnostic, pkg Package, hasMissingDeps bool) (bool, bool, error) {
	ctx, done := event.Start(ctx, "source.diagnostics", tag.Package.Of(pkg.ID()))
	_ = ctx // circumvent SA4006
	defer done()

	diagSets := make(map[span.URI]*diagnosticSet)
	for _, e := range pkg.GetErrors() {
		diag := &Diagnostic{
			Message:  e.Message,
			Range:    e.Range,
			Severity: protocol.SeverityError,
		}
		set, ok := diagSets[e.URI]
		if !ok {
			set = &diagnosticSet{}
			diagSets[e.URI] = set
		}
		switch e.Kind {
		case ParseError:
			set.parseErrors = append(set.parseErrors, diag)
			diag.Source = "syntax"
		case TypeError:
			set.typeErrors = append(set.typeErrors, diag)
			diag.Source = "compiler"
		case ListError:
			set.listErrors = append(set.listErrors, diag)
			diag.Source = "go list"
		}
	}
	var nonEmptyDiagnostics, hasTypeErrors bool // track if we actually send non-empty diagnostics
	for uri, set := range diagSets {
		// Don't report type errors if there are parse errors or list errors.
		diags := set.typeErrors
		if len(set.parseErrors) > 0 {
			diags, nonEmptyDiagnostics = set.parseErrors, true
		} else if len(set.listErrors) > 0 {
			// Only show list errors if the package has missing dependencies.
			if hasMissingDeps {
				diags, nonEmptyDiagnostics = set.listErrors, true
			}
		} else if len(set.typeErrors) > 0 {
			hasTypeErrors = true
		}
		if err := addReports(ctx, snapshot, reports, uri, diags...); err != nil {
			return false, false, err
		}
	}
	return nonEmptyDiagnostics, hasTypeErrors, nil
}

func missingModulesDiagnostics(ctx context.Context, snapshot Snapshot, reports map[FileIdentity][]*Diagnostic, missingModules map[string]*modfile.Require, uri span.URI) error {
	if len(missingModules) == 0 {
		return nil
	}
	fh, err := snapshot.GetFile(ctx, uri)
	if err != nil {
		return err
	}
	pgh := snapshot.View().Session().Cache().ParseGoHandle(ctx, fh, ParseHeader)
	file, _, m, _, err := pgh.Parse(ctx)
	if err != nil {
		return err
	}
	// Make a dependency->import map to improve performance when finding missing dependencies.
	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 the go file has 0 imports, then we do not need to check for missing dependencies.
	if len(imports) == 0 {
		return nil
	}
	if reports[fh.Identity()] == nil {
		reports[fh.Identity()] = []*Diagnostic{}
	}
	for mod, req := range missingModules {
		if req.Syntax == nil {
			continue
		}
		imp, ok := imports[mod]
		if !ok {
			continue
		}
		spn, err := span.NewRange(snapshot.View().Session().Cache().FileSet(), imp.Path.Pos(), imp.Path.End()).Span()
		if err != nil {
			return err
		}
		rng, err := m.Range(spn)
		if err != nil {
			return err
		}
		reports[fh.Identity()] = append(reports[fh.Identity()], &Diagnostic{
			Message:  fmt.Sprintf("%s is not in your go.mod file.", req.Mod.Path),
			Range:    rng,
			Source:   "go mod tidy",
			Severity: protocol.SeverityWarning,
		})
	}
	return nil
}

func analyses(ctx context.Context, snapshot Snapshot, reports map[FileIdentity][]*Diagnostic, ph PackageHandle, analyses map[string]Analyzer) error {
	var analyzers []*analysis.Analyzer
	for _, a := range analyses {
		if !a.Enabled(snapshot) {
			continue
		}
		analyzers = append(analyzers, a.Analyzer)
	}
	analysisErrors, err := snapshot.Analyze(ctx, ph.ID(), analyzers...)
	if err != nil {
		return err
	}

	// Report diagnostics and errors from root analyzers.
	for _, e := range analysisErrors {
		// If the diagnostic comes from a "convenience" analyzer, it is not
		// meant to provide diagnostics, but rather only suggested fixes.
		// Skip these types of errors in diagnostics; we will use their
		// suggested fixes when providing code actions.
		if isConvenienceAnalyzer(e.Category) {
			continue
		}
		// This is a bit of a hack, but clients > 3.15 will be able to grey out unnecessary code.
		// If we are deleting code as part of all of our suggested fixes, assume that this is dead code.
		// TODO(golang/go#34508): Return these codes from the diagnostics themselves.
		var tags []protocol.DiagnosticTag
		if onlyDeletions(e.SuggestedFixes) {
			tags = append(tags, protocol.Unnecessary)
		}
		if err := addReports(ctx, snapshot, reports, e.URI, &Diagnostic{
			Range:    e.Range,
			Message:  e.Message,
			Source:   e.Category,
			Severity: protocol.SeverityWarning,
			Tags:     tags,
			Related:  e.Related,
		}); err != nil {
			return err
		}
	}
	return nil
}

func clearReports(ctx context.Context, snapshot Snapshot, reports map[FileIdentity][]*Diagnostic, uri span.URI) {
	fh := snapshot.FindFile(uri)
	if fh == nil {
		return
	}
	reports[fh.Identity()] = []*Diagnostic{}
}

func addReports(ctx context.Context, snapshot Snapshot, reports map[FileIdentity][]*Diagnostic, uri span.URI, diagnostics ...*Diagnostic) error {
	fh := snapshot.FindFile(uri)
	if fh == nil {
		return nil
	}
	existingDiagnostics, ok := reports[fh.Identity()]
	if !ok {
		return fmt.Errorf("diagnostics for unexpected file %s", uri)
	}
	if len(diagnostics) == 1 {
		d1 := diagnostics[0]
		if _, ok := snapshot.View().Options().TypeErrorAnalyzers[d1.Source]; ok {
			for i, d2 := range existingDiagnostics {
				if r := protocol.CompareRange(d1.Range, d2.Range); r != 0 {
					continue
				}
				if d1.Message != d2.Message {
					continue
				}
				reports[fh.Identity()][i].Tags = append(reports[fh.Identity()][i].Tags, d1.Tags...)
			}
			return nil
		}
	}
	reports[fh.Identity()] = append(reports[fh.Identity()], diagnostics...)
	return nil
}

// onlyDeletions returns true if all of the suggested fixes are deletions.
func onlyDeletions(fixes []SuggestedFix) bool {
	for _, fix := range fixes {
		for _, edits := range fix.Edits {
			for _, edit := range edits {
				if edit.NewText != "" {
					return false
				}
				if protocol.ComparePosition(edit.Range.Start, edit.Range.End) == 0 {
					return false
				}
			}
		}
	}
	return len(fixes) > 0
}

// hasUndeclaredErrors returns true if a package has a type error
// about an undeclared symbol.
func hasUndeclaredErrors(pkg Package) bool {
	for _, err := range pkg.GetErrors() {
		if err.Kind != TypeError {
			continue
		}
		if strings.Contains(err.Message, "undeclared name:") {
			return true
		}
	}
	return false
}

func isConvenienceAnalyzer(category string) bool {
	for _, a := range DefaultOptions().ConvenienceAnalyzers {
		if category == a.Analyzer.Name {
			return true
		}
	}
	return false
}
