// Copyright 2021 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 report

import (
	"errors"
	"fmt"
	"net/url"
	"path/filepath"
	"regexp"
	"strings"
	"unicode"

	"golang.org/x/exp/slices"
	"golang.org/x/mod/module"
	"golang.org/x/vulndb/internal/cveschema5"
	"golang.org/x/vulndb/internal/derrors"
	"golang.org/x/vulndb/internal/ghsa"
	"golang.org/x/vulndb/internal/osv"
	"golang.org/x/vulndb/internal/osvutils"
	"golang.org/x/vulndb/internal/proxy"
	"golang.org/x/vulndb/internal/stdlib"
)

func (m *Module) checkModVersions(pc *proxy.Client) error {
	var notFound []string
	var nonCanonical []string
	for _, vr := range m.Versions {
		for _, v := range []string{vr.Introduced, vr.Fixed} {
			if v == "" {
				continue
			}
			c, err := pc.CanonicalModulePath(m.Module, v)
			if err != nil {
				notFound = append(notFound, v)
				continue
			}
			if c != m.Module {
				nonCanonical = append(nonCanonical, fmt.Sprintf("%s (canonical:%s)", v, c))
			}
		}
	}
	var sb strings.Builder
	nf, nc := len(notFound), len(nonCanonical)
	if nf > 0 {
		if nf == 1 {
			sb.WriteString(fmt.Sprintf("version %s does not exist", notFound[0]))
		} else {
			sb.WriteString(fmt.Sprintf("%d versions do not exist: %s", nf, strings.Join(notFound, ", ")))
		}
	}
	if nc > 0 {
		if nf > 0 {
			sb.WriteString(" and ")
		}
		sb.WriteString(fmt.Sprintf("module is not canonical at %d version(s): %s", nc, strings.Join(nonCanonical, ", ")))
	}
	if s := sb.String(); s != "" {
		return errors.New(s)
	}
	return nil
}

var missing = "missing"

func (m *Module) lintVersions(l *linter) {
	if u := len(m.UnsupportedVersions); u > 0 {
		l.Group("unsupported_versions").Errorf("found %d (want none)", u)
	}

	vl := l.Group("versions")
	ranges := AffectedRanges(m.Versions)
	if v := m.VulnerableAt; v != "" {
		affected, err := osvutils.AffectsSemver(ranges, v)
		if err != nil {
			vl.Error(err)
		} else if !affected {
			l.Group("vulnerable_at").Errorf("%s is not inside vulnerable range", v)
		}
	} else {
		if err := osvutils.ValidateRanges(ranges); err != nil {
			vl.Error(err)
		}
	}
}

func (r *Report) lintCVEs(l *linter) {
	for i, cve := range r.CVEs {
		if !cveschema5.IsCVE(cve) {
			l.Group(name("cves", i, cve)).Error("malformed cve identifier")
		}
	}
}

func (r *Report) lintGHSAs(l *linter) {
	for i, g := range r.GHSAs {
		if !ghsa.IsGHSA(g) {
			l.Group(name("ghsas", i, g)).Errorf("%s is not a valid GHSA", g)
		}
	}
}

func name(field string, index int, name string) string {
	fieldIndex := fmt.Sprintf("%s[%d]", field, index)
	if name != "" {
		return fmt.Sprintf("%s %q", fieldIndex, name)
	}
	return fieldIndex
}

func (r *Report) lintRelated(l *linter) {
	if len(r.Related) == 0 {
		// Not required.
		return
	}

	aliases := r.Aliases()
	for i, related := range r.Related {
		rl := l.Group(name("related", i, related))
		// In most cases, the related list is very short, so there's no
		// need create a map of aliases.
		if slices.Contains(aliases, related) {
			rl.Error("also listed among aliases")
		}
		if !isIdentifier(related) {
			rl.Error("not a recognized identifier (CVE, GHSA or Go ID)")
		}
	}
}

func isIdentifier(id string) bool {
	return cveschema5.IsCVE(id) || ghsa.IsGHSA(id) || IsGoID(id)
}

var goIDregexp = regexp.MustCompile(`^GO-\d{4}-\d{4,}$`)

func IsGoID(s string) bool {
	return goIDregexp.MatchString(s)
}

const maxLineLength = 80

func (r *Report) lintLineLength(l *linter, content string) {
	for _, line := range strings.Split(content, "\n") {
		if len(line) <= maxLineLength {
			continue
		}
		if !strings.Contains(line, " ") {
			continue // A single long word is OK.
		}
		l.Errorf("contains line > %v characters long: %q", maxLineLength, line)
		return
	}
}

// Regex patterns for standard links.
var (
	prRegex       = regexp.MustCompile(`https://go.dev/cl/\d+`)
	commitRegex   = regexp.MustCompile(`https://go.googlesource.com/[^/]+/\+/([^/]+)`)
	issueRegex    = regexp.MustCompile(`https://go.dev/issue/\d+`)
	announceRegex = regexp.MustCompile(`https://groups.google.com/g/golang-(announce|dev|nuts)/c/([^/]+)`)

	nistRegex     = regexp.MustCompile(`^https://nvd.nist.gov/vuln/detail/(` + cveschema5.RegexStr + `)$`)
	ghsaLinkRegex = regexp.MustCompile(`^https://github.com/.*/(` + ghsa.Regex + `)$`)
	mitreRegex    = regexp.MustCompile(`^https://cve.mitre.org/.*(` + cveschema5.RegexStr + `)$`)
)

func (ref *Reference) lint(l *linter, r *Report) {
	// Checks specific to first-party reports.
	if r.IsFirstParty() {
		switch ref.Type {
		case osv.ReferenceTypeAdvisory:
			l.Errorf("%q: advisory reference must not be set for first-party issues", ref.URL)
		case osv.ReferenceTypeFix:
			if !prRegex.MatchString(ref.URL) && !commitRegex.MatchString(ref.URL) {
				l.Errorf("%q: fix reference must match %q or %q", ref.URL, prRegex, commitRegex)
			}
		case osv.ReferenceTypeReport:
			if !issueRegex.MatchString(ref.URL) {
				l.Errorf("%q: report reference must match regex %q", ref.URL, issueRegex)
			}
		case osv.ReferenceTypeWeb:
			if !announceRegex.MatchString(ref.URL) {
				l.Errorf("%q: web reference must match regex %q", ref.URL, announceRegex)
			}
		}
	}

	if !slices.Contains(osv.ReferenceTypes, ref.Type) {
		l.Errorf("invalid reference type %q", ref.Type)
	}
	u := ref.URL
	if _, err := url.ParseRequestURI(u); err != nil {
		l.Error("invalid URL")
	}
	if fixed := fixURL(u); fixed != u {
		l.Errorf("should be %q (can be auto-fixed)", fixURL(u))
	}
	if ref.Type != osv.ReferenceTypeAdvisory {
		// An ADVISORY reference to a CVE/GHSA indicates that it
		// is the canonical source of information on this vuln.
		//
		// A reference to a CVE/GHSA that is not an alias of this
		// report indicates that it may contain related information.
		//
		// A reference to a CVE/GHSA that appears in the CVEs/GHSAs
		// aliases is redundant.
		for _, re := range []*regexp.Regexp{nistRegex, mitreRegex, ghsaLinkRegex} {
			if m := re.FindStringSubmatch(ref.URL); len(m) > 0 {
				id := m[1]
				if slices.Contains(r.CVEs, id) || slices.Contains(r.GHSAs, id) {
					l.Errorf("redundant non-advisory reference to %v", id)
				}
			}
		}
	}
}

func (r *Report) lintReferences(l *linter) {
	for i, ref := range r.References {
		rl := l.Group(name("references", i, ref.URL))
		ref.lint(rl, r)
	}

	// Find missing references.
	rl := l.Group("references")
	advisoryCount := r.countAdvisories()
	if advisoryCount > 1 {
		rl.Errorf("too many advisories (found %d, want <=1)", advisoryCount)
	}
	if !r.IsExcluded() {
		if r.IsFirstParty() {
			var hasFixLink, hasReportLink, hasAnnounceLink bool
			for _, ref := range r.References {
				switch ref.Type {
				case osv.ReferenceTypeFix:
					hasFixLink = true
				case osv.ReferenceTypeReport:
					hasReportLink = true
				case osv.ReferenceTypeWeb:
					if announceRegex.MatchString(ref.URL) {
						hasAnnounceLink = true
					}
				}
			}
			if !hasFixLink {
				rl.Error("must contain at least one fix")
			}
			if !hasReportLink {
				rl.Error("must contain at least one report")
			}
			if !hasAnnounceLink {
				rl.Errorf("must contain an announcement link matching regex %q", announceRegex)
			}
		}
		if r.missingAdvisory(advisoryCount) {
			rl.Error("missing advisory (required because report has no description)")
		}
	}
}

func (r *Report) countAdvisories() int {
	advisoryCount := 0
	for _, ref := range r.References {
		if ref.Type == osv.ReferenceTypeAdvisory {
			advisoryCount++
		}
	}
	return advisoryCount
}

func (r *Report) missingAdvisory(advisoryCount int) bool {
	return !r.IsExcluded() && !r.IsFirstParty() &&
		advisoryCount == 0 && r.Description == "" && r.CVEMetadata == nil
}

func (d *Description) lint(l *linter, r *Report) {
	desc := d.String()

	checkNoMarkdown(l, desc)
	r.lintLineLength(l, desc)
	if !r.IsExcluded() && desc == "" {
		if r.CVEMetadata != nil {
			l.Error("missing (reports with Go CVEs must have a description)")
		}
	}
}

func (s *Summary) lint(l *linter, r *Report) {
	summary := s.String()
	if !r.IsExcluded() && len(summary) == 0 {
		l.Error(missing)
	}
	// Nothing to lint.
	if len(summary) == 0 {
		return
	}
	if hasTODO(summary) {
		l.Error(hasTODOErr)
		// No need to keep linting, as this is likely a placeholder value.
		return
	}
	checkNoMarkdown(l, summary)
	if ln := len(summary); ln > 100 {
		l.Errorf("too long (found %d characters, want <=100)", ln)
	}
	if strings.HasSuffix(summary, ".") {
		l.Error("must not end in a period (should be a phrase, not a sentence)")
	}
	for i, r := range summary {
		if i != 0 {
			break
		}
		if !unicode.IsUpper(r) {
			l.Error("must begin with a capital letter")
		}
	}

	// Summary must contain one of the listed module or package
	// paths. (Except in the "std" module, where a specific package
	// must be mentioned).
	// If there are no such paths listed in the report at all,
	// another lint will complain, so reduce noise by not erroring here.
	if paths := r.nonStdPaths(); len(paths) > 0 {
		if ok := containsPath(summary, paths); !ok {
			l.Errorf("must contain an affected module or package path (e.g. %q)", paths[0])
		}
	}
}

// containsPath returns whether the summary contains one of
// the paths in paths.
// As a special case, if the summary contains a word that contains a "/"
// and is a prefix of a path, the function returns true. This gives us a
// workaround for reports that affect a lot of modules and/or have very long
// module paths.
func containsPath(summary string, paths []string) bool {
	if len(paths) == 0 {
		return false
	}

	for _, possiblePath := range strings.Fields(summary) {
		possiblePath := strings.TrimRight(possiblePath, ":,.")
		for _, path := range paths {
			if possiblePath == path {
				return true
			}
			if strings.Contains(possiblePath, "/") &&
				strings.HasPrefix(path, possiblePath) {
				return true
			}
		}
	}

	return false
}

// nonStdPaths returns all module and package paths (except "std")
// mentioned in the report.
func (r *Report) nonStdPaths() (paths []string) {
	for _, m := range r.Modules {
		if m.Module != "" && m.Module != stdlib.ModulePath {
			paths = append(paths, m.Module)
		}
		for _, p := range m.Packages {
			if p.Package != "" {
				paths = append(paths, p.Package)
			}
		}
	}
	return paths
}

func (r *Report) IsExcluded() bool {
	return r.Excluded != ""
}

var (
	errWrongDir = errors.New("report is in incorrect directory")
	errWrongID  = errors.New("report ID mismatch")
)

// CheckFilename errors if the filename is inconsistent with the report.
func (r *Report) CheckFilename(filename string) (err error) {
	defer derrors.Wrap(&err, "CheckFilename(%q)", filename)

	dir := filepath.Base(filepath.Dir(filename)) // innermost folder
	excluded := r.IsExcluded()

	if excluded && dir != excludedFolder {
		return fmt.Errorf("%w (want %s, found %s)", errWrongDir, excludedFolder, dir)
	}

	if !excluded && dir != reportsFolder {
		return fmt.Errorf("%w (want %s, found %s)", errWrongDir, reportsFolder, dir)
	}

	wantID := GoID(filename)
	if r.ID != wantID {
		return fmt.Errorf("%w (want %s, found %s)", errWrongID, wantID, r.ID)
	}

	return nil
}

// Lint checks the content of a Report and outputs a list of strings
// representing lint errors.
// TODO: It might make sense to include warnings or informational things
// alongside errors, especially during for use during the triage process.
func (r *Report) Lint(pc *proxy.Client) []string {
	result := r.lint(pc)
	if pc == nil {
		result = append(result, "proxy client is nil; cannot perform all lint checks")
	}
	return result
}

// LintAsNotes works like Lint, but modifies r by adding any lints found
// to the notes section, instead of returning them.
// Removes any pre-existing lint notes.
// Returns true if any lints were found.
func (r *Report) LintAsNotes(pc *proxy.Client) bool {
	r.Notes = slices.DeleteFunc(r.Notes, func(n *Note) bool {
		return n.Type == NoteTypeLint
	})

	if lints := r.Lint(pc); len(lints) > 0 {
		slices.Sort(lints)
		for _, lint := range lints {
			r.AddNote(NoteTypeLint, lint)
		}
		return true
	}

	return false
}

func (r *Report) AddNote(t NoteType, format string, v ...any) {
	r.Notes = append(r.Notes, &Note{
		Body: fmt.Sprintf(format, v...),
		Type: t,
	})
}

// LintOffline performs all lint checks that don't require a network connection.
func (r *Report) LintOffline() []string {
	return r.lint(nil)
}

func (r *Report) lint(pc *proxy.Client) []string {
	l := NewLinter("")

	if r.ID == "" {
		l.Group("id").Error(missing)
	}

	r.Summary.lint(l.Group("summary"), r)
	r.Description.lint(l.Group("description"), r)
	r.Excluded.lint(l.Group("excluded"))

	r.lintModules(l, pc)

	r.CVEMetadata.lint(l.Group("cve_metadata"), r)

	if r.IsExcluded() && len(r.Aliases()) == 0 {
		l.Group("cves,ghsas").Error()
	}

	r.lintCVEs(l)
	r.lintGHSAs(l)
	r.lintRelated(l)

	r.lintReferences(l)

	return l.Errors()
}

func (m *Module) lint(l *linter, r *Report, pc *proxy.Client) {
	if m.Module == "" {
		l.Error("no module name")
	}

	if !m.IsFirstParty() && pc != nil {
		if err := m.checkModVersions(pc); err != nil {
			l.Error(err)
		}
	}

	if m.IsFirstParty() && len(m.Packages) == 0 {
		l.Error("no packages")
	}

	for i, p := range m.Packages {
		p.lint(l.Group(name("packages", i, p.Package)), m, r)
	}

	m.lintVersions(l)
}

func (p *Package) lint(l *linter, m *Module, r *Report) {
	if p.Package == "" {
		l.Error("no package name")
	} else {
		if m.Module != stdlib.ModulePath {
			if !strings.HasPrefix(p.Package, m.Module) {
				l.Error("module must be a prefix of package")
			}
		} else {
			if p.Package == "runtime" && len(p.Symbols) != 0 {
				l.Errorf("runtime package must have no symbols (found %d)", len(p.Symbols))
			}
			// As a special case, check for "cmd/" packages that are
			// mistakenly placed in the "std" module.
			if strings.HasPrefix(p.Package, stdlib.ToolchainModulePath) {
				l.Error("must be in module cmd")
			}
		}

		if !m.IsFirstParty() {
			if err := module.CheckImportPath(p.Package); err != nil {
				l.Error(err)
			}
		}
	}

	if !r.IsExcluded() {
		if m.VulnerableAt == "" && p.SkipFix == "" {
			l.Error("at least one of vulnerable_at and skip_fix must be set")
		}
	}
}

func (r *Report) lintModules(l *linter, pc *proxy.Client) {
	if r.Excluded != "NOT_GO_CODE" && len(r.Modules) == 0 {
		l.Group("modules").Error(missing)
	}

	for i, m := range r.Modules {
		m.lint(l.Group(name("modules", i, m.Module)), r, pc)
	}
}

func (r *Report) IsFirstParty() bool {
	for _, m := range r.Modules {
		if m.IsFirstParty() {
			return true
		}
	}
	return false
}

func (m *Module) IsFirstParty() bool {
	return stdlib.IsStdModule(m.Module) || stdlib.IsCmdModule(m.Module)
}

func (e *ExcludedReason) lint(l *linter) {
	if e == nil || *e == "" {
		return
	}
	if !slices.Contains(ExcludedReasons, *e) {
		l.Errorf("excluded reason (%q) is not a valid excluded reason (accepted: %v)", *e, ExcludedReasons)
	}
}

func (m *CVEMeta) lint(l *linter, r *Report) {
	if m == nil {
		return
	}

	il := l.Group("id")
	if m.ID == "" {
		il.Error(missing)
	} else if !cveschema5.IsCVE(m.ID) {
		il.Error("not a valid CVE")
	}

	cl := l.Group("cwe")
	if m.CWE == "" {
		cl.Error(missing)
	}
	if hasTODO(m.CWE) {
		cl.Error(hasTODOErr)
	}

	r.lintLineLength(l.Group("description"), m.Description)
}

var hasTODOErr = "contains a TODO"

func hasTODO(s string) bool {
	return strings.Contains(s, "TODO")
}

// Regular expressions for markdown-style elements that shouldn't
// be in our descriptions/summaries.
var (
	backtickRE = regexp.MustCompile("(`.*`)")
	linkRE     = regexp.MustCompile(`(\[.*\]\(.*\))`)
	headingRE  = regexp.MustCompile(`(#+ )`)
)

func checkNoMarkdown(l *linter, s string) {
	for _, re := range []*regexp.Regexp{backtickRE, linkRE, headingRE} {
		matches := re.FindStringSubmatch(s)
		if len(matches) > 0 {
			l.Errorf("possible markdown formatting (found %s)", matches[1])
		}
	}
}
