import os
from pathlib import Path
from typing import Dict, Any

from checkov.common.bridgecrew.platform_integration import BcPlatformIntegration
from checkov.common.bridgecrew.vulnerability_scanning.integrations.twistcli import TwistcliIntegration
from checkov.common.util.str_utils import removeprefix


class DockerImageScanningIntegration(TwistcliIntegration):
    async def report_results_async(
        self,
        twistcli_scan_result: Dict[str, Any],
        bc_platform_integration: BcPlatformIntegration,
        bc_api_key: str,
        file_path: Path,
        **kwargs: Any,
    ) -> int:
        return await super().report_results_async(
            twistcli_scan_result=twistcli_scan_result,
            bc_platform_integration=bc_platform_integration,
            bc_api_key=bc_api_key,
            file_path=file_path,
            file_content=kwargs["file_content"],
            docker_image_name=kwargs["docker_image_name"],
        )

    # can be removed, if image scanning is also using report_results_asyncio
    # make sure to remove it only after validating it isn't used from the platform
    def report_results(
        self,
        twistcli_scan_result: Dict[str, Any],
        file_path: Path,
        **kwargs: Any,
    ) -> None:
        super().report_results(
            twistcli_scan_result=twistcli_scan_result,
            file_path=file_path,
            file_content=kwargs['file_content'],
            docker_image_name=kwargs['docker_image_name'],
        )

    def create_report(
        self,
        twistcli_scan_result: Dict[str, Any],
        bc_platform_integration: BcPlatformIntegration,
        file_path: Path,
        file_content: str,
        docker_image_name: str,
    ) -> Dict[str, Any]:
        results_dict = self._get_results_dict(twistcli_scan_result)
        payload = {
            "dockerImageName": docker_image_name,
            "dockerFilePath": removeprefix(str(file_path), os.getenv("BC_ROOT_DIR", "")),
            "dockerFileContent": file_content,
            "type": "Image",
            "sourceId": bc_platform_integration.repo_id,
            "branch": bc_platform_integration.repo_branch,
            "sourceType": bc_platform_integration.bc_source.name,
            "vulnerabilities": self.get_vulnerabilities_for_report(results_dict),
            "packages": self.get_packages_for_report(results_dict),
        }
        if bc_platform_integration.cicd_details:
            payload["cicdDetails"] = bc_platform_integration.cicd_details
        return payload

    @staticmethod
    def _get_results_dict(twistcli_scan_result: Dict[str, Any]) -> Dict[str, Any]:
        try:
            results = twistcli_scan_result["results"]
            # we expect that there is exactly 1 scanned dokcer-image.
            if len(results) != 1:
                raise Exception(f'expected length of \"results\": 1. found: {len(results)}', results)
        except KeyError:
            raise Exception("the key \"results\" expected to be existing in:", twistcli_scan_result)
        return results[0]


docker_image_scanning_integration = DockerImageScanningIntegration()
