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

import (
	"time"

	"golang.org/x/mod/semver"
	"golang.org/x/vulndb/report"
)

// DBIndex contains a mapping of vulnerable packages to the
// last time a new vulnerability was added to the database.
// TODO: this is probably not the correct place to put this
// type, since it's not really an OSV/CVF thing, but rather
// vulndb implementatiion detail.
type DBIndex map[string]time.Time

type Severity int

const (
	SevNone Severity = iota
	SevLow
	SevMedium
	SevHigh
	SevCritical
)

var strToSev = map[string]Severity{
	// "": SevNone,
	"low":      SevLow,
	"medium":   SevMedium,
	"high":     SevHigh,
	"critical": SevCritical,
}

type Type int

const (
	TypeUnspecified Type = iota
	TypeGit
	TypeSemver
)

type Ecosystem string

const GoEcosystem Ecosystem = "go"

type Package struct {
	Name      string
	Ecosystem Ecosystem
}

type AffectsRange struct {
	Type       Type
	Introduced string
	Fixed      string
}

func (ar AffectsRange) containsSemver(v string) bool {
	if ar.Type != TypeSemver {
		return false
	}

	return (ar.Introduced == "" || semver.Compare(v, ar.Introduced) >= 0) &&
		(ar.Fixed == "" || semver.Compare(v, ar.Fixed) < 0)
}

type Affects struct {
	Ranges []AffectsRange
}

func generateAffects(versions []report.VersionRange) Affects {
	a := Affects{}
	for _, v := range versions {
		a.Ranges = append(a.Ranges, AffectsRange{
			Type:       TypeSemver,
			Introduced: v.Introduced,
			Fixed:      v.Fixed,
		})
	}
	return a
}

func (a Affects) AffectsSemver(v string) bool {
	if len(a.Ranges) == 0 {
		// No ranges implies all versions are affected
		return true
	}
	var semverRangePresent bool
	for _, r := range a.Ranges {
		if r.Type != TypeSemver {
			continue
		}
		semverRangePresent = true
		if r.containsSemver(v) {
			return true
		}
	}
	// If there were no semver ranges present we
	// assume that all semvers are affected, similarly
	// to how to we assume all semvers are affected
	// if there are no ranges at all.
	return !semverRangePresent
}

type GoSpecific struct {
	Symbols []string `json:",omitempty"`
	GOOS    []string `json:",omitempty"`
	GOARCH  []string `json:",omitempty"`
	URL     string
}

// Entry represents a OSV style JSON vulnerability database
// entry
type Entry struct {
	ID                string
	Package           Package
	Summary           string
	Details           string
	Severity          Severity
	Affects           Affects
	ReferenceURLs     []string   `json:"reference_urls,omitempty"`
	Aliases           []string   `json:",omitempty"`
	EcosystemSpecific GoSpecific `json:"ecosystem_specific,omitempty"`
	LastModified      time.Time  `json:"last_modified"`
}

func Generate(id string, url string, r report.Report) []Entry {
	importPath := r.Module
	if r.Package != "" {
		importPath = r.Package
	}
	entry := Entry{
		ID: id,
		Package: Package{
			Name:      importPath,
			Ecosystem: GoEcosystem,
		},
		Summary:      "", // TODO: think if we want to populate this in reports
		Details:      r.Description,
		Affects:      generateAffects(r.Versions),
		LastModified: time.Now(),
		EcosystemSpecific: GoSpecific{
			Symbols: r.Symbols,
			GOOS:    r.OS,
			GOARCH:  r.Arch,
			URL:     url,
		},
	}

	if r.Severity != "" {
		entry.Severity = strToSev[r.Severity]
	} else {
		// Default to medium or none?
		entry.Severity = SevMedium
	}

	if r.Links.PR != "" {
		entry.ReferenceURLs = append(entry.ReferenceURLs, r.Links.PR)
	}
	if r.Links.Commit != "" {
		entry.ReferenceURLs = append(entry.ReferenceURLs, r.Links.Commit)
	}
	if r.Links.Context != nil {
		entry.ReferenceURLs = append(entry.ReferenceURLs, r.Links.Context...)
	}

	if r.CVE != "" {
		entry.Aliases = []string{r.CVE}
	}

	entries := []Entry{entry}

	// It would be better if this was just a recursive thing probably
	for _, additional := range r.AdditionalPackages {
		entryCopy := entry
		additionalImportPath := additional.Module
		if additional.Package != "" {
			additionalImportPath = additional.Package
		}
		entryCopy.Package.Name = additionalImportPath
		entryCopy.EcosystemSpecific.Symbols = additional.Symbols
		entryCopy.Affects = generateAffects(additional.Versions)

		entries = append(entries, entryCopy)
	}

	return entries
}
