package converter

import (
	"gitlab.com/gitlab-org/security-products/analyzers/trivy-k8s-wrapper/data/analyzers/report"
	"gitlab.com/gitlab-org/security-products/analyzers/trivy-k8s-wrapper/prototool"
)

// Converter translate prototool packages to report packages
type Converter struct{}

func (c *Converter) ToIdentifiers(proto []*prototool.Identifier) []report.Identifier {
	identifiers := make([]report.Identifier, len(proto))
	for i, p := range proto {
		identifiers[i] = report.Identifier{
			Type:  report.IdentifierType(p.Type),
			Name:  p.Name,
			Value: p.Value,
			URL:   p.Url,
		}
	}
	return identifiers
}

func (c *Converter) ToLinks(proto []*prototool.Link) []report.Link {
	links := make([]report.Link, len(proto))
	for i, l := range proto {
		links[i] = report.Link{
			Name: l.Name,
			URL:  l.Url,
		}
	}
	return links
}

func (c *Converter) ToLocation(proto *prototool.Location) report.Location {
	return report.Location{
		Dependency: &report.Dependency{
			Package: report.Package{Name: proto.Dependency.Package.Name},
			Version: proto.Dependency.Version,
		},
		KubernetesResource: c.ToKubernetesResource(proto.KubernetesResource),
		Image:              proto.Image,
		OperatingSystem:    proto.OperatingSystem,
	}
}

func (c *Converter) ToKubernetesResource(proto *prototool.KubernetesResource) *report.KubernetesResource {
	return &report.KubernetesResource{
		Namespace:     proto.Namespace,
		Name:          proto.Name,
		Kind:          proto.Kind,
		AgentID:       proto.AgentId,
		ContainerName: proto.ContainerName,
	}
}

// Adapted from severityNames in Trivy-db https://gitlab.com/gitlab-org/security-products/dependencies/trivy-db/-/blob/2bd1364579ec652f8f595c4a61595fd9575e8496/pkg/types/types.go#L35
const (
	SeverityCritical = "CRITICAL"
	SeverityHigh     = "HIGH"
	SeverityMedium   = "MEDIUM"
	SeverityLow      = "LOW"

	SeverityNone    = "NONE" // Kept for legacy reasons since starboard contains this severity level
	SeverityUnknown = "UNKNOWN"
)

var severityMapping = map[string]report.SeverityLevel{
	SeverityCritical: report.SeverityLevelCritical,
	SeverityHigh:     report.SeverityLevelHigh,
	SeverityMedium:   report.SeverityLevelMedium,
	SeverityLow:      report.SeverityLevelLow,
	SeverityNone:     report.SeverityLevelInfo,
	SeverityUnknown:  report.SeverityLevelUnknown,
}

func (c *Converter) ToSeverity(severity string) report.SeverityLevel {
	sev, ok := severityMapping[severity]
	if !ok {
		return report.SeverityLevelUnknown
	}
	return sev
}
