package types

import (
	ftypes "github.com/aquasecurity/fanal/types"
	"github.com/aquasecurity/trivy-db/pkg/types"
)

// DetectedVulnerability holds the information of detected vulnerabilities
type DetectedVulnerability struct {
	VulnerabilityID  string       `json:",omitempty"`
	PkgName          string       `json:",omitempty"`
	InstalledVersion string       `json:",omitempty"`
	FixedVersion     string       `json:",omitempty"`
	Layer            ftypes.Layer `json:",omitempty"`
	SeveritySource   string       `json:",omitempty"`
	PrimaryURL       string       `json:",omitempty"`

	types.Vulnerability
}

// BySeverity implements sort.Interface based on the Severity field.
type BySeverity []DetectedVulnerability

// Len returns the length of DetectedVulnerabilities
func (v BySeverity) Len() int { return len(v) }

// Less compares 2 DetectedVulnerabilities based on package name, severity and vulnerabilityID
func (v BySeverity) Less(i, j int) bool {
	if v[i].PkgName != v[j].PkgName {
		return v[i].PkgName < v[j].PkgName
	} else if v[i].InstalledVersion != v[j].InstalledVersion {
		return v[i].InstalledVersion < v[j].InstalledVersion
	}
	ret := types.CompareSeverityString(
		v[j].Severity, v[i].Severity,
	)
	if ret != 0 {
		return ret > 0
	}
	return v[i].VulnerabilityID < v[j].VulnerabilityID
}

// Swap swaps 2 vulnerability
func (v BySeverity) Swap(i, j int) { v[i], v[j] = v[j], v[i] }
