// Package vulns provides utilities for working with vulnerability schemas.
package vulns

import (
	"strings"

	"github.com/ossf/osv-schema/bindings/go/osvschema"
)

// PackageKey uniquely identifies a package in a vulnerability.
type PackageKey struct {
	Name      string
	Ecosystem string
	Purl      string
}

// NewPackageKey creates a PackageKey from osvschema.Package.
func NewPackageKey(pkg *osvschema.Package) PackageKey {
	return PackageKey{
		Name:      pkg.GetName(),
		Ecosystem: pkg.GetEcosystem(),
		Purl:      pkg.GetPurl(),
	}
}

// GetFixedVersions returns a map of fixed versions for each package, or a map of empty slices if no fixed versions are available
func GetFixedVersions(v *osvschema.Vulnerability) map[PackageKey][]string {
	output := map[PackageKey][]string{}
	for _, a := range v.GetAffected() {
		if a.GetPackage() == nil {
			continue
		}
		packageKey := NewPackageKey(a.GetPackage())
		packageKey.Purl = ""
		for _, r := range a.GetRanges() {
			for _, e := range r.GetEvents() {
				if e.GetFixed() != "" {
					output[packageKey] = append(output[packageKey], e.GetFixed())
					if strings.Contains(packageKey.Ecosystem, ":") {
						unversionedKey := packageKey
						unversionedKey.Ecosystem = strings.Split(packageKey.Ecosystem, ":")[0]
						output[unversionedKey] = append(output[unversionedKey], e.GetFixed())
					}
				}
			}
		}
	}

	return output
}
