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

import (
	"bytes"
	"context"
	"fmt"
	"sort"
	"strings"

	"golang.org/x/mod/modfile"
	"golang.org/x/mod/semver"
	"golang.org/x/tools/gopls/internal/file"
	"golang.org/x/tools/gopls/internal/lsp/cache"
	"golang.org/x/tools/gopls/internal/lsp/protocol"
	"golang.org/x/tools/gopls/internal/settings"
	"golang.org/x/tools/gopls/internal/vulncheck"
	"golang.org/x/tools/gopls/internal/vulncheck/govulncheck"
	"golang.org/x/tools/gopls/internal/vulncheck/osv"
	"golang.org/x/tools/internal/event"
)

func Hover(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle, position protocol.Position) (*protocol.Hover, error) {
	var found bool
	for _, uri := range snapshot.ModFiles() {
		if fh.URI() == uri {
			found = true
			break
		}
	}

	// We only provide hover information for the view's go.mod files.
	if !found {
		return nil, nil
	}

	ctx, done := event.Start(ctx, "mod.Hover")
	defer done()

	// Get the position of the cursor.
	pm, err := snapshot.ParseMod(ctx, fh)
	if err != nil {
		return nil, fmt.Errorf("getting modfile handle: %w", err)
	}
	offset, err := pm.Mapper.PositionOffset(position)
	if err != nil {
		return nil, fmt.Errorf("computing cursor position: %w", err)
	}

	// If the cursor position is on a module statement
	if hover, ok := hoverOnModuleStatement(ctx, pm, offset, snapshot, fh); ok {
		return hover, nil
	}
	return hoverOnRequireStatement(ctx, pm, offset, snapshot, fh)
}

func hoverOnRequireStatement(ctx context.Context, pm *cache.ParsedModule, offset int, snapshot *cache.Snapshot, fh file.Handle) (*protocol.Hover, error) {
	// Confirm that the cursor is at the position of a require statement.
	var req *modfile.Require
	var startOffset, endOffset int
	for _, r := range pm.File.Require {
		dep := []byte(r.Mod.Path)
		s, e := r.Syntax.Start.Byte, r.Syntax.End.Byte
		i := bytes.Index(pm.Mapper.Content[s:e], dep)
		if i == -1 {
			continue
		}
		// Shift the start position to the location of the
		// dependency within the require statement.
		startOffset, endOffset = s+i, e
		if startOffset <= offset && offset <= endOffset {
			req = r
			break
		}
	}
	// TODO(hyangah): find position for info about vulnerabilities in Go

	// The cursor position is not on a require statement.
	if req == nil {
		return nil, nil
	}

	// Get the vulnerability info.
	fromGovulncheck := true
	vs := snapshot.Vulnerabilities(fh.URI())[fh.URI()]
	if vs == nil && snapshot.Options().Vulncheck == settings.ModeVulncheckImports {
		var err error
		vs, err = snapshot.ModVuln(ctx, fh.URI())
		if err != nil {
			return nil, err
		}
		fromGovulncheck = false
	}
	affecting, nonaffecting, osvs := lookupVulns(vs, req.Mod.Path, req.Mod.Version)

	// Get the `go mod why` results for the given file.
	why, err := snapshot.ModWhy(ctx, fh)
	if err != nil {
		return nil, err
	}
	explanation, ok := why[req.Mod.Path]
	if !ok {
		return nil, nil
	}

	// Get the range to highlight for the hover.
	// TODO(hyangah): adjust the hover range to include the version number
	// to match the diagnostics' range.
	rng, err := pm.Mapper.OffsetRange(startOffset, endOffset)
	if err != nil {
		return nil, err
	}
	options := snapshot.Options()
	isPrivate := snapshot.IsGoPrivatePath(req.Mod.Path)
	header := formatHeader(req.Mod.Path, options)
	explanation = formatExplanation(explanation, req, options, isPrivate)
	vulns := formatVulnerabilities(affecting, nonaffecting, osvs, options, fromGovulncheck)

	return &protocol.Hover{
		Contents: protocol.MarkupContent{
			Kind:  options.PreferredContentFormat,
			Value: header + vulns + explanation,
		},
		Range: rng,
	}, nil
}

func hoverOnModuleStatement(ctx context.Context, pm *cache.ParsedModule, offset int, snapshot *cache.Snapshot, fh file.Handle) (*protocol.Hover, bool) {
	module := pm.File.Module
	if module == nil {
		return nil, false // no module stmt
	}
	if offset < module.Syntax.Start.Byte || offset > module.Syntax.End.Byte {
		return nil, false // cursor not in module stmt
	}

	rng, err := pm.Mapper.OffsetRange(module.Syntax.Start.Byte, module.Syntax.End.Byte)
	if err != nil {
		return nil, false
	}
	fromGovulncheck := true
	vs := snapshot.Vulnerabilities(fh.URI())[fh.URI()]

	if vs == nil && snapshot.Options().Vulncheck == settings.ModeVulncheckImports {
		vs, err = snapshot.ModVuln(ctx, fh.URI())
		if err != nil {
			return nil, false
		}
		fromGovulncheck = false
	}
	modpath := "stdlib"
	goVersion := snapshot.View().GoVersionString()
	affecting, nonaffecting, osvs := lookupVulns(vs, modpath, goVersion)
	options := snapshot.Options()
	vulns := formatVulnerabilities(affecting, nonaffecting, osvs, options, fromGovulncheck)

	return &protocol.Hover{
		Contents: protocol.MarkupContent{
			Kind:  options.PreferredContentFormat,
			Value: vulns,
		},
		Range: rng,
	}, true
}

func formatHeader(modpath string, options *settings.Options) string {
	var b strings.Builder
	// Write the heading as an H3.
	b.WriteString("#### " + modpath)
	if options.PreferredContentFormat == protocol.Markdown {
		b.WriteString("\n\n")
	} else {
		b.WriteRune('\n')
	}
	return b.String()
}

func lookupVulns(vulns *vulncheck.Result, modpath, version string) (affecting, nonaffecting []*govulncheck.Finding, osvs map[string]*osv.Entry) {
	if vulns == nil || len(vulns.Entries) == 0 {
		return nil, nil, nil
	}
	for _, finding := range vulns.Findings {
		vuln, typ := foundVuln(finding)
		if vuln.Module != modpath {
			continue
		}
		// It is possible that the source code was changed since the last
		// govulncheck run and information in the `vulns` info is stale.
		// For example, imagine that a user is in the middle of updating
		// problematic modules detected by the govulncheck run by applying
		// quick fixes. Stale diagnostics can be confusing and prevent the
		// user from quickly locating the next module to fix.
		// Ideally we should rerun the analysis with the updated module
		// dependencies or any other code changes, but we are not yet
		// in the position of automatically triggering the analysis
		// (govulncheck can take a while). We also don't know exactly what
		// part of source code was changed since `vulns` was computed.
		// As a heuristic, we assume that a user upgrades the affecting
		// module to the version with the fix or the latest one, and if the
		// version in the require statement is equal to or higher than the
		// fixed version, skip the vulnerability information in the hover.
		// Eventually, the user has to rerun govulncheck.
		if finding.FixedVersion != "" && semver.IsValid(version) && semver.Compare(finding.FixedVersion, version) <= 0 {
			continue
		}
		switch typ {
		case vulnCalled:
			affecting = append(affecting, finding)
		case vulnImported:
			nonaffecting = append(nonaffecting, finding)
		}
	}

	// Remove affecting elements from nonaffecting.
	// An OSV entry can appear in both lists if an OSV entry covers
	// multiple packages imported but not all vulnerable symbols are used.
	// The current wording of hover message doesn't clearly
	// present this case well IMO, so let's skip reporting nonaffecting.
	if len(affecting) > 0 && len(nonaffecting) > 0 {
		affectingSet := map[string]bool{}
		for _, f := range affecting {
			affectingSet[f.OSV] = true
		}
		n := 0
		for _, v := range nonaffecting {
			if !affectingSet[v.OSV] {
				nonaffecting[n] = v
				n++
			}
		}
		nonaffecting = nonaffecting[:n]
	}
	sort.Slice(nonaffecting, func(i, j int) bool { return nonaffecting[i].OSV < nonaffecting[j].OSV })
	sort.Slice(affecting, func(i, j int) bool { return affecting[i].OSV < affecting[j].OSV })
	return affecting, nonaffecting, vulns.Entries
}

func fixedVersion(fixed string) string {
	if fixed == "" {
		return "No fix is available."
	}
	return "Fixed in " + fixed + "."
}

func formatVulnerabilities(affecting, nonaffecting []*govulncheck.Finding, osvs map[string]*osv.Entry, options *settings.Options, fromGovulncheck bool) string {
	if len(osvs) == 0 || (len(affecting) == 0 && len(nonaffecting) == 0) {
		return ""
	}
	byOSV := func(findings []*govulncheck.Finding) map[string][]*govulncheck.Finding {
		m := make(map[string][]*govulncheck.Finding)
		for _, f := range findings {
			m[f.OSV] = append(m[f.OSV], f)
		}
		return m
	}
	affectingByOSV := byOSV(affecting)
	nonaffectingByOSV := byOSV(nonaffecting)

	// TODO(hyangah): can we use go templates to generate hover messages?
	// Then, we can use a different template for markdown case.
	useMarkdown := options.PreferredContentFormat == protocol.Markdown

	var b strings.Builder

	if len(affectingByOSV) > 0 {
		// TODO(hyangah): make the message more eyecatching (icon/codicon/color)
		if len(affectingByOSV) == 1 {
			fmt.Fprintf(&b, "\n**WARNING:** Found %d reachable vulnerability.\n", len(affectingByOSV))
		} else {
			fmt.Fprintf(&b, "\n**WARNING:** Found %d reachable vulnerabilities.\n", len(affectingByOSV))
		}
	}
	for id, findings := range affectingByOSV {
		fix := fixedVersion(findings[0].FixedVersion)
		pkgs := vulnerablePkgsInfo(findings, useMarkdown)
		osvEntry := osvs[id]

		if useMarkdown {
			fmt.Fprintf(&b, "- [**%v**](%v) %v%v\n%v\n", id, href(id), osvEntry.Summary, pkgs, fix)
		} else {
			fmt.Fprintf(&b, "  - [%v] %v (%v) %v%v\n", id, osvEntry.Summary, href(id), pkgs, fix)
		}
	}
	if len(nonaffecting) > 0 {
		if fromGovulncheck {
			fmt.Fprintf(&b, "\n**Note:** The project imports packages with known vulnerabilities, but does not call the vulnerable code.\n")
		} else {
			fmt.Fprintf(&b, "\n**Note:** The project imports packages with known vulnerabilities. Use `govulncheck` to check if the project uses vulnerable symbols.\n")
		}
	}
	for k, findings := range nonaffectingByOSV {
		fix := fixedVersion(findings[0].FixedVersion)
		pkgs := vulnerablePkgsInfo(findings, useMarkdown)
		osvEntry := osvs[k]

		if useMarkdown {
			fmt.Fprintf(&b, "- [%v](%v) %v%v\n%v\n", k, href(k), osvEntry.Summary, pkgs, fix)
		} else {
			fmt.Fprintf(&b, "  - [%v] %v (%v) %v\n%v\n", k, osvEntry.Summary, href(k), pkgs, fix)
		}
	}
	b.WriteString("\n")
	return b.String()
}

func vulnerablePkgsInfo(findings []*govulncheck.Finding, useMarkdown bool) string {
	var b strings.Builder
	seen := map[string]bool{}
	for _, f := range findings {
		p := f.Trace[0].Package
		if !seen[p] {
			seen[p] = true
			if useMarkdown {
				b.WriteString("\n  * `")
			} else {
				b.WriteString("\n    ")
			}
			b.WriteString(p)
			if useMarkdown {
				b.WriteString("`")
			}
		}
	}
	return b.String()
}

func formatExplanation(text string, req *modfile.Require, options *settings.Options, isPrivate bool) string {
	text = strings.TrimSuffix(text, "\n")
	splt := strings.Split(text, "\n")
	length := len(splt)

	var b strings.Builder

	// If the explanation is 2 lines, then it is of the form:
	// # golang.org/x/text/encoding
	// (main module does not need package golang.org/x/text/encoding)
	if length == 2 {
		b.WriteString(splt[1])
		return b.String()
	}

	imp := splt[length-1] // import path
	reference := imp
	// See golang/go#36998: don't link to modules matching GOPRIVATE.
	if !isPrivate && options.PreferredContentFormat == protocol.Markdown {
		target := imp
		if strings.ToLower(options.LinkTarget) == "pkg.go.dev" {
			target = strings.Replace(target, req.Mod.Path, req.Mod.String(), 1)
		}
		reference = fmt.Sprintf("[%s](%s)", imp, cache.BuildLink(options.LinkTarget, target, ""))
	}
	b.WriteString("This module is necessary because " + reference + " is imported in")

	// If the explanation is 3 lines, then it is of the form:
	// # golang.org/x/tools
	// modtest
	// golang.org/x/tools/go/packages
	if length == 3 {
		msg := fmt.Sprintf(" `%s`.", splt[1])
		b.WriteString(msg)
		return b.String()
	}

	// If the explanation is more than 3 lines, then it is of the form:
	// # golang.org/x/text/language
	// rsc.io/quote
	// rsc.io/sampler
	// golang.org/x/text/language
	b.WriteString(":\n```text")
	dash := ""
	for _, imp := range splt[1 : length-1] {
		dash += "-"
		b.WriteString("\n" + dash + " " + imp)
	}
	b.WriteString("\n```")
	return b.String()
}
