from sator_core.models.product import Product
from sator_core.models.vulnerability import VulnerabilityLocator, VulnerabilityAttributes, VulnerabilityMetadata

from sator_core.ports.driven.persistence.storage import StoragePersistencePort
from sator_core.ports.driving.analysis.attributes.vulnerability import VulnerabilityAttributesAnalysisPort


class VulnerabilityAttributesAnalysis(VulnerabilityAttributesAnalysisPort):
    def __init__(self, storage_port: StoragePersistencePort):
        self.storage_port = storage_port

    def analyze_vulnerability_attributes(self, vulnerability_id: str) -> VulnerabilityLocator | None:
        locator = self.storage_port.load(VulnerabilityLocator, vulnerability_id)

        if locator:
            return locator

        attributes = self.storage_port.load(VulnerabilityAttributes, vulnerability_id)

        if attributes and attributes.product:
            product = self._find_vulnerable_product(vulnerability_id, attributes.product)

            if product:
                # TODO: validate version/s
                # TODO: validate if file name/path
                locator = VulnerabilityLocator(
                    product=product, version=attributes.version, function=attributes.function, file=attributes.file
                )

                self.storage_port.save(locator, vulnerability_id)
                return locator

        return None

    def _find_vulnerable_product(self, vulnerability_id: str, product_name: str) -> Product | None:
        metadata = self.storage_port.load(VulnerabilityMetadata, vulnerability_id)

        if metadata:
            for affected_product in metadata.affected_products:
                # TODO: maybe consider vendor name as well
                if affected_product.name.lower() == product_name.lower():
                    return affected_product

                # TODO: check for similarity to determine if it's the same product

        return None
