package vulnerability

import (
	"fmt"
	"time"

	"github.com/fatih/color"
)

type Severity int

const (
	SeverityUnknown Severity = iota
	SeverityLow
	SeverityMedium
	SeverityHigh
	SeverityCritical
)

var (
	SeverityNames = []string{
		"UNKNOWN",
		"LOW",
		"MEDIUM",
		"HIGH",
		"CRITICAL",
	}
	SeverityColor = []func(a ...interface{}) string{
		color.New(color.FgCyan).SprintFunc(),
		color.New(color.FgBlue).SprintFunc(),
		color.New(color.FgYellow).SprintFunc(),
		color.New(color.FgHiRed).SprintFunc(),
		color.New(color.FgRed).SprintFunc(),
	}
)

func NewSeverity(severity string) (Severity, error) {
	for i, name := range SeverityNames {
		if severity == name {
			return Severity(i), nil
		}
	}
	return SeverityUnknown, fmt.Errorf("unknown severity: %s", severity)
}

func CompareSeverityString(sev1, sev2 string) bool {
	s1, _ := NewSeverity(sev1)
	s2, _ := NewSeverity(sev2)
	return s1 < s2
}

func ColorizeSeverity(severity string) string {
	for i, name := range SeverityNames {
		if severity == name {
			return SeverityColor[i](severity)
		}
	}
	return color.New(color.FgBlue).SprintFunc()(severity)
}

func (s Severity) String() string {
	return SeverityNames[s]
}

type LastUpdated struct {
	Date time.Time
}
type Vulnerability struct {
	ID          string // e.g. CVE-2019-8331, OSVDB-104365
	CvssScore   float64
	CvssScoreV3 float64
	Severity    Severity
	SeverityV3  Severity
	References  []string
	Title       string
	Description string
}

type Advisory struct {
	VulnerabilityID string
	FixedVersion    string
}

type DetectedVulnerability struct {
	VulnerabilityID  string
	PkgName          string
	InstalledVersion string
	FixedVersion     string

	Title       string
	Description string
	Severity    string
	References  []string
}
