from pathlib import Path
from typing import Any, Optional

from yanga.cmake.artifacts_locator import BuildArtifact, CMakeArtifactsLocator
from yanga.cmake.cmake_backend import CMakeCommand, CMakeComment, CMakeCustomCommand, CMakeCustomTarget, CMakeElement
from yanga.cmake.generator import CMakeGenerator
from yanga.domain.execution_context import ExecutionContext, UserRequest, UserRequestScope
from yanga.domain.reports import ReportRelevantFiles, ReportRelevantFileType


class TargetsDataCMakeGenerator(CMakeGenerator):
    def __init__(
        self,
        execution_context: ExecutionContext,
        output_dir: Path,
        config: Optional[dict[str, Any]] = None,
    ) -> None:
        super().__init__(execution_context, output_dir, config)
        self.artifacts_locator = CMakeArtifactsLocator(output_dir, execution_context.create_artifacts_locator())

    def generate(self) -> list[CMakeElement]:
        elements: list[CMakeElement] = []
        elements.append(CMakeComment(f"Generated by {self.__class__.__name__}"))
        elements.extend(self.create_variant_cmake_elements())
        return elements

    def create_variant_cmake_elements(self) -> list[CMakeElement]:
        elements: list[CMakeElement] = []
        # Create custom command to generate the targets data documentation
        targets_data_doc_file = self.artifacts_locator.cmake_build_dir.joinpath("targets_data.md")
        targets_data_file = self.artifacts_locator.get_build_artifact(BuildArtifact.TARGETS_DATA)
        platform_targets = ["all"]
        if self.execution_context.platform:
            if self.execution_context.platform.build_targets:
                platform_targets = self.execution_context.platform.build_targets
        targets_data_cmd = CMakeCustomCommand(
            description="Generate variant targets data documentation",
            depends=[targets_data_file],
            outputs=[targets_data_doc_file],
            commands=[
                CMakeCommand(
                    "yanga_cmd",
                    [
                        "targets_doc",
                        "--variant-targets-data-file",
                        targets_data_file,
                        "--output-file",
                        targets_data_doc_file,
                        "--targets",
                        *platform_targets,
                    ],
                ),
            ],
        )
        elements.append(targets_data_cmd)
        # Add custom target for the objects deps report
        targets_data_target = UserRequest(
            UserRequestScope.VARIANT,
            target="targets_data",
        )

        elements.append(
            CMakeCustomTarget(
                targets_data_target.target_name,
                "Generate targets data report",
                [],
                targets_data_cmd.outputs,
            )
        )

        # Register the variant targets data documentation file as relevant for the variant report
        self.execution_context.data_registry.insert(
            ReportRelevantFiles(
                target=targets_data_target,
                files_to_be_included=[targets_data_doc_file.to_path()],
                file_type=ReportRelevantFileType.OTHER,
            ),
            targets_data_target.target_name,
        )
        return elements
