// Copyright 2022 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 (
	"encoding/json"
	"os"
	"path/filepath"
	"regexp"
	"sort"
	"strings"
	"time"

	"golang.org/x/exp/maps"
	"golang.org/x/vulndb/internal/derrors"
	"golang.org/x/vulndb/internal/osv"
	"golang.org/x/vulndb/internal/stdlib"
)

var (
	// osvDir is the name of the directory in the vulndb repo that
	// contains reports.
	OSVDir = "data/osv"

	// SchemaVersion is used to indicate which version of the OSV schema a
	// particular vulnerability was exported with.
	SchemaVersion = "1.3.1"
)

// ToOSV creates an osv.Entry for a report.
// lastModified is the time the report should be considered to have
// been most recently modified.
func (r *Report) ToOSV(lastModified time.Time) osv.Entry {
	var credits []osv.Credit
	for _, credit := range r.Credits {
		credits = append(credits, osv.Credit{
			Name: credit,
		})
	}

	var withdrawn *osv.Time
	if r.Withdrawn != nil {
		withdrawn = &osv.Time{Time: *r.Withdrawn}
	}

	// If the report has no description, use the summary for now.
	// TODO(https://go.dev/issues/61201): Remove this once pkgsite and
	// govulncheck can robustly display summaries in place of details.
	details := r.Description
	if details == "" {
		details = r.Summary.String()
	}

	entry := osv.Entry{
		ID:               r.ID,
		Published:        osv.Time{Time: r.Published},
		Modified:         osv.Time{Time: lastModified},
		Withdrawn:        withdrawn,
		Related:          r.Related,
		Summary:          toParagraphs(r.Summary.String()),
		Details:          toParagraphs(details),
		Credits:          credits,
		SchemaVersion:    SchemaVersion,
		DatabaseSpecific: &osv.DatabaseSpecific{URL: GoAdvisory(r.ID)},
	}

	for _, m := range r.Modules {
		entry.Affected = append(entry.Affected, toAffected(m))
	}
	for _, ref := range r.References {
		entry.References = append(entry.References, osv.Reference{
			Type: ref.Type,
			URL:  ref.URL,
		})
	}
	entry.Aliases = r.Aliases()
	return entry
}

func (r *Report) OSVFilename() string {
	return filepath.Join(OSVDir, r.ID+".json")
}

// ReadOSV reads an osv.Entry from a file.
func ReadOSV(filename string) (entry osv.Entry, err error) {
	derrors.Wrap(&err, "ReadOSV(%s)", filename)
	if err = UnmarshalFromFile(filename, &entry); err != nil {
		return osv.Entry{}, err
	}
	return entry, nil
}

func UnmarshalFromFile(path string, v any) (err error) {
	content, err := os.ReadFile(path)
	if err != nil {
		return err
	}
	if err = json.Unmarshal(content, v); err != nil {
		return err
	}
	return nil
}

// ModulesForEntry returns the list of modules affected by an OSV entry.
func ModulesForEntry(entry osv.Entry) []string {
	mods := map[string]bool{}
	for _, a := range entry.Affected {
		mods[a.Module.Path] = true
	}
	return maps.Keys(mods)
}

func AffectedRanges(versions []VersionRange) []osv.Range {
	a := osv.Range{Type: osv.RangeTypeSemver}
	if len(versions) == 0 || versions[0].Introduced == "" {
		a.Events = append(a.Events, osv.RangeEvent{Introduced: "0"})
	}
	for _, v := range versions {
		if v.Introduced != "" {
			a.Events = append(a.Events, osv.RangeEvent{Introduced: v.Introduced})
		}
		if v.Fixed != "" {
			a.Events = append(a.Events, osv.RangeEvent{Fixed: v.Fixed})
		}
	}
	return []osv.Range{a}
}

var (
	listMarker     = regexp.MustCompile(`([\*\-\+>]|\d+[.\)]) [^\n]+`)
	spaces         = regexp.MustCompile(`[[:space:]]+`)
	paragraphBreak = regexp.MustCompile(`\s*\n{2,}\s*`)
)

// toParagraphs removes unnecessary whitespace (spaces, tabs and newlines) from
// a string, but preserves paragraph breaks (indicated by two consecutive
// newlines), and Markdown-style list breaks.
func toParagraphs(s string) string {
	if len(s) == 0 {
		return ""
	}
	var result strings.Builder
	result.Grow(len(s))
	for i, line := range strings.Split(strings.TrimSpace(s), "\n") {
		// Replace consecutive space characters with single spaces.
		line = spaces.ReplaceAllString(strings.TrimSpace(line), " ")
		// An empty line represents a paragraph break.
		if len(line) == 0 {
			result.WriteString("\n\n")
			continue
		}
		if i > 0 {
			// Preserve line break if the line starts with a Markdown list marker.
			if loc := listMarker.FindStringIndex(line); loc != nil && loc[0] == 0 {
				result.WriteRune('\n')
			} else {
				result.WriteRune(' ')
			}
		}
		result.WriteString(line)
	}
	// Replace instances of 2 or more newlines with exactly two newlines.
	return paragraphBreak.ReplaceAllString(result.String(), "\n\n")
}

func toOSVPackages(pkgs []*Package) (imps []osv.Package) {
	for _, p := range pkgs {
		syms := append([]string{}, p.Symbols...)
		syms = append(syms, p.DerivedSymbols...)
		sort.Strings(syms)
		imps = append(imps, osv.Package{
			Path:    p.Package,
			GOOS:    p.GOOS,
			GOARCH:  p.GOARCH,
			Symbols: syms,
		})
	}
	return imps
}

func toAffected(m *Module) osv.Affected {
	name := m.Module
	switch name {
	case stdlib.ModulePath:
		name = osv.GoStdModulePath
	case stdlib.ToolchainModulePath:
		name = osv.GoCmdModulePath
	}
	return osv.Affected{
		Module: osv.Module{
			Path:      name,
			Ecosystem: osv.GoEcosystem,
		},
		Ranges: AffectedRanges(m.Versions),
		EcosystemSpecific: &osv.EcosystemSpecific{
			Packages: toOSVPackages(m.Packages),
		},
	}
}
