// 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.View().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()
}
