package vulnerability

import (
	"fmt"

	"github.com/anchore/grype/grype/pkg/qualifier"
	"github.com/anchore/grype/grype/version"
	"github.com/anchore/grype/internal/log"
	"github.com/anchore/syft/syft/cpe"
)

type Reference struct {
	ID        string
	Namespace string
	Internal  any
}

type Vulnerability struct {
	Reference
	Status                 string
	PackageName            string
	Constraint             version.Constraint
	PackageQualifiers      []qualifier.Qualifier
	CPEs                   []cpe.CPE
	Fix                    Fix
	Advisories             []Advisory
	RelatedVulnerabilities []Reference
	Metadata               *Metadata
	Unaffected             bool
}

func (v Vulnerability) String() string {
	constraint := "(none)"
	if v.Constraint != nil {
		constraint = v.Constraint.String()
	}
	return fmt.Sprintf("Vuln(id=%s constraint=%q qualifiers=%+v)", v.ID, constraint, v.PackageQualifiers)
}

// LogDropped should be called with a properly resolved vulnerability ID in every location in-memory vulnerabilities'
// are filtered out by any process. this can be the first stop to diagnosing why certain vulnerabilities do not show up
//
//go:noinline
func LogDropped(id, op, dropReason string, context any) {
	log.WithFields("op", op, "reason", dropReason, "vulnerability", id, "context", context).Trace("dropped vuln")
}
