// Copyright 2024 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 main

import (
	"context"
	"fmt"
	"net/http"
	"os"
	"strings"

	"golang.org/x/exp/slices"
	"golang.org/x/vulndb/cmd/vulnreport/log"
	"golang.org/x/vulndb/internal/idstr"
	"golang.org/x/vulndb/internal/issues"
	"golang.org/x/vulndb/internal/osv"
	"golang.org/x/vulndb/internal/report"
	"golang.org/x/vulndb/internal/symbols"
	"golang.org/x/vulndb/internal/triage/priority"
)

type creator struct {
	assignee string
	created  []*yamlReport

	// If non-zero, use this review status
	// instead of the default for new reports.
	reviewStatus report.ReviewStatus

	*fixer
	*xrefer
	*suggester
}

func (c *creator) setup(ctx context.Context, env environment) (err error) {
	user := *user
	if user == "" {
		user = os.Getenv("GITHUB_USER")
	}
	c.assignee = user

	rs, ok := report.ToReviewStatus(*reviewStatus)
	if !ok {
		return fmt.Errorf("invalid -status=%s", rs)
	}
	c.reviewStatus = rs

	c.fixer = new(fixer)
	c.xrefer = new(xrefer)
	if *useAI {
		c.suggester = new(suggester)
	}
	return setupAll(ctx, env, c.fixer, c.xrefer, c.suggester)
}

func (c *creator) skip(input any) string {
	iss := input.(*issues.Issue)

	if c.assignee != "" && iss.Assignee != c.assignee {
		return fmt.Sprintf("assignee = %q, not %q", iss.Assignee, c.assignee)
	}

	return skip(iss, c.xrefer)
}

func skip(iss *issues.Issue, x *xrefer) string {
	if iss.HasLabel(labelOutOfScope) {
		return "out of scope"
	}

	if iss.HasLabel(labelDuplicate) {
		return "duplicate issue"
	}

	if iss.HasLabel(labelSuggestedEdit) {
		return "suggested edit"
	}

	// indicates that there is already a report for this
	// vuln but the report needs to be updated
	if iss.HasLabel(labelNeedsAlias) {
		return "existing report needs alias"
	}

	if iss.HasLabel(labelPossibleDuplicate) {
		return "possible duplicate"
	}

	if iss.HasLabel(labelPossiblyNotGo) {
		return "possibly not Go"
	}

	if x.rc.HasReport(iss.Number) {
		return "already has report"
	}

	return ""
}

func (c *creator) reportFromIssue(ctx context.Context, iss *issues.Issue) error {
	r, err := c.reportFromMeta(ctx, &reportMeta{
		id:           iss.NewGoID(),
		excluded:     excludedReason(iss),
		modulePath:   modulePath(iss),
		aliases:      aliases(iss),
		reviewStatus: reviewStatusOf(iss, c.reviewStatus),
		originalCVE:  originalCVE(iss),
	})
	if err != nil {
		return err
	}
	return c.write(ctx, r)
}

func originalCVE(iss *issues.Issue) string {
	aliases := aliases(iss)
	if iss.HasLabel(labelFirstParty) && len(aliases) == 1 && idstr.IsCVE(aliases[0]) {
		return aliases[0]
	}
	return ""
}

func reviewStatusOf(iss *issues.Issue, reviewStatus report.ReviewStatus) report.ReviewStatus {
	d := defaultReviewStatus(iss)
	// If a valid review status is provided, it overrides the priority label.
	if reviewStatus != 0 {
		if d != reviewStatus {
			log.Warnf("issue #%d: should be %s based on label(s) but this was overridden with the -status=%s flag", iss.Number, d, reviewStatus)
		}
		return reviewStatus
	}
	return d
}

func defaultReviewStatus(iss *issues.Issue) report.ReviewStatus {
	if iss.HasLabel(labelHighPriority) ||
		iss.HasLabel(labelDirect) ||
		iss.HasLabel(labelFirstParty) {
		return report.Reviewed
	}

	return report.Unreviewed
}

func (c *creator) metaToSource(ctx context.Context, meta *reportMeta) report.Source {
	if cveID := meta.originalCVE; cveID != "" {
		log.Infof("%s: creating original report for Go-CNA-assigned %s", meta.id, cveID)
		return report.OriginalCVE(cveID)
	}

	if src := c.sourceFromBestAlias(ctx, meta.aliases, *preferCVE); src != nil {
		log.Infof("%s: picked %s as best source alias (from [%s])", meta.id, src.SourceID(),
			strings.Join(meta.aliases, ", "))
		return src
	}

	log.Infof("%s: no suitable alias found, creating basic report", meta.id)
	return report.Original()
}

func (c *creator) rawReport(ctx context.Context, meta *reportMeta) *report.Report {
	return report.New(c.metaToSource(ctx, meta), c.pxc,
		report.WithGoID(meta.id),
		report.WithModulePath(meta.modulePath),
		report.WithAliases(meta.aliases),
		report.WithReviewStatus(meta.reviewStatus),
		report.WithUnexcluded(meta.unexcluded),
	)
}

func (c *creator) reportFromMeta(ctx context.Context, meta *reportMeta) (*yamlReport, error) {
	// Find the underlying module if the "module" provided is actually a package path.
	if module, err := c.pxc.FindModule(meta.modulePath); err == nil { // no error
		meta.modulePath = module
	}
	meta.aliases = c.allAliases(ctx, meta.aliases)
	raw := c.rawReport(ctx, meta)

	if meta.excluded != "" {
		raw = &report.Report{
			ID: meta.id,
			Modules: []*report.Module{
				{
					Module: meta.modulePath,
				},
			},
			Excluded: meta.excluded,
			CVEs:     raw.CVEs,
			GHSAs:    raw.GHSAs,
		}
	}

	// The initial quick triage algorithm doesn't know about all
	// affected modules, so double check the priority after the
	// report is created.
	if raw.IsUnreviewed() {
		pr, _ := c.reportPriority(raw)
		if pr.Priority == priority.High {
			log.Warnf("%s: re-generating; vuln is high priority and should be REVIEWED; reason: %s", raw.ID, pr.Reason)
			meta.reviewStatus = report.Reviewed
			raw = c.rawReport(ctx, meta)
		}
	}

	fname, err := raw.YAMLFilename()
	if err != nil {
		return nil, err
	}
	r := &yamlReport{Report: raw, Filename: fname}

	// Find any additional aliases referenced by the source aliases.
	r.addMissingAliases(ctx, c.aliasFinder)

	if c.suggester != nil {
		suggestions, err := c.suggest(ctx, r, 1)
		if err != nil {
			r.AddNote(report.NoteTypeCreate, "failed to get AI-generated suggestions")
			log.Warnf("%s: failed to get AI-generated suggestions: %v", r.ID, err)
		} else {
			log.Infof("%s: applying AI-generated suggestion", r.ID)
			r.applySuggestion(suggestions[0])
		}
	}

	if *populateSymbols {
		log.Infof("%s: attempting to auto-populate symbols (this may take a while...)", r.ID)
		if err := symbols.Populate(r.Report, false); err != nil {
			r.AddNote(report.NoteTypeCreate, "failed to auto-populate symbols")
			log.Warnf("%s: could not auto-populate symbols: %s", r.ID, err)
		} else {
			if err := r.checkSymbols(); err != nil {
				log.Warnf("%s: auto-populated symbols have error(s): %s", r.ID, err)
			}
		}
	}

	switch {
	case raw.IsExcluded():
		// nothing
	case raw.IsUnreviewed():
		r.removeUnreachableRefs()
	default:
		// Regular, full-length reports.
		addTODOs(r)
		if xrefs := c.xref(r); len(xrefs) != 0 {
			log.Infof("%s: found cross-references: %s", r.ID, xrefs)
		}
	}
	return r, nil
}

func (r *yamlReport) removeUnreachableRefs() {
	r.Report.References = slices.DeleteFunc(r.Report.References, func(r *report.Reference) bool {
		resp, err := http.Head(r.URL)
		if err != nil {
			return true
		}
		defer resp.Body.Close()
		return resp.StatusCode == http.StatusNotFound
	})
}

func (c *creator) write(ctx context.Context, r *yamlReport) error {
	if r.IsReviewed() || r.IsExcluded() {
		if err := c.fileWriter.write(r); err != nil {
			return err
		}
	} else { // unreviewed
		addNotes := true
		if err := c.fixAndWriteAll(ctx, r, addNotes); err != nil {
			return err
		}
	}
	c.created = append(c.created, r)
	return nil
}

const (
	labelDuplicate         = "duplicate"
	labelDirect            = "Direct External Report"
	labelSuggestedEdit     = "Suggested Edit"
	labelNeedsAlias        = "NeedsAlias"
	labelTriaged           = "triaged"
	labelHighPriority      = "high priority"
	labelFirstParty        = "first party"
	labelPossibleDuplicate = "possible duplicate"
	labelPossiblyNotGo     = "possibly not Go"
	labelOutOfScope        = "excluded: OUT_OF_SCOPE"
)

func excludedReason(iss *issues.Issue) report.ExcludedReason {
	for _, label := range iss.Labels {
		if reason, ok := report.FromLabel(label); ok {
			return reason
		}
	}
	return ""
}

func modulePath(iss *issues.Issue) string {
	for _, p := range strings.Fields(iss.Title) {
		if p == "x/vulndb:" {
			continue
		}
		if strings.HasSuffix(p, ":") || strings.Contains(p, "/") {
			// Remove backslashes.
			return strings.ReplaceAll(strings.TrimSuffix(p, ":"), "\"", "")
		}
	}
	return ""
}

func aliases(iss *issues.Issue) (aliases []string) {
	for _, p := range strings.Fields(iss.Title) {
		if idstr.IsAliasType(p) {
			aliases = append(aliases, strings.TrimSuffix(p, ","))
		}
	}
	return aliases
}

// Data that can be combined with a source vulnerability
// to create a new report.
type reportMeta struct {
	id                   string
	modulePath           string
	aliases              []string
	excluded, unexcluded report.ExcludedReason
	reviewStatus         report.ReviewStatus
	originalCVE          string
}

const todo = "TODO: "

// addTODOs adds "TODO" comments to unfilled fields of r.
func addTODOs(r *yamlReport) {
	if r.Excluded != "" {
		return
	}
	if len(r.Modules) == 0 {
		r.Modules = append(r.Modules, &report.Module{
			Packages: []*report.Package{{}},
		})
	}
	for _, m := range r.Modules {
		if m.Module == "" {
			m.Module = todo + "affected module path"
		}
		if len(m.Versions) == 0 {
			m.Versions = report.Versions{
				report.Introduced(todo + "introduced version (blank if unknown)"),
				report.Fixed(todo + "fixed version"),
			}
		}
		if m.VulnerableAt == nil {
			m.VulnerableAt = report.VulnerableAt(todo + "a version at which the package is vulnerable")
		}
		if len(m.Packages) == 0 {
			m.Packages = []*report.Package{
				{
					Package: todo + "affected package path(s) - blank if all",
				},
			}
		}
		for _, p := range m.Packages {
			if p.Package == "" {
				p.Package = todo + "affected package path"
			}
			if len(p.Symbols) == 0 {
				p.Symbols = []string{todo + "affected symbol(s) - blank if all"}
			}
		}
	}
	if r.Summary == "" {
		r.Summary = todo + "short (one phrase) summary of the form '<Problem> in <module>(s)'"
	}
	if r.Description == "" {
		r.Description = todo + "description of the vulnerability"
	}
	if len(r.Credits) == 0 {
		r.Credits = []string{todo + "who discovered/reported this vulnerability (optional)"}
	}
	if r.CVEMetadata == nil && len(r.CVEs) == 0 {
		r.CVEs = []string{todo + "CVE id(s) for this vulnerability"}
	}
	if r.CVEMetadata != nil && r.CVEMetadata.CWE == "" {
		r.CVEMetadata.CWE = todo + "CWE ID"
	}
	addReferenceTODOs(r)
}

// addReferenceTODOs adds a TODO for each important reference type not
// already present in the report.
func addReferenceTODOs(r *yamlReport) {
	todos := []*report.Reference{
		{Type: osv.ReferenceTypeAdvisory, URL: "TODO: canonical security advisory"},
		{Type: osv.ReferenceTypeReport, URL: "TODO: issue tracker link"},
		{Type: osv.ReferenceTypeFix, URL: "TODO: PR or commit (commit preferred)"}}

	types := make(map[osv.ReferenceType]bool)
	for _, r := range r.References {
		types[r.Type] = true
	}
	for _, todo := range todos {
		if !types[todo.Type] {
			r.References = append(r.References, todo)
		}
	}
}
