from pathlib import Path
from typing import Any, Optional

from yanga.cmake.artifacts_locator import 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, ReportRelevantHtmlContent


class ObjectsDepsCMakeGenerator(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] = []
        objects_deps_html_rel_path = "objects_deps.html"
        objects_deps_html = self.artifacts_locator.cmake_variant_reports_dir.joinpath(objects_deps_html_rel_path)
        objects_deps_cmake_cmd = CMakeCustomCommand(
            description="Run clanguru to generate the objects dependencies report",
            outputs=[objects_deps_html],
            depends=["compile"],
            commands=[
                CMakeCommand(
                    "${CMAKE_COMMAND}",
                    [
                        "-E",
                        "make_directory",
                        self.artifacts_locator.cmake_variant_reports_dir,
                    ],
                ),
                CMakeCommand(
                    "clanguru",
                    [
                        "analyze",
                        "--compilation-database",
                        self.artifacts_locator.cmake_build_dir.joinpath("compile_commands.json"),
                        "--output-file",
                        objects_deps_html,
                    ],
                ),
            ],
        )
        elements.append(objects_deps_cmake_cmd)
        # Add custom target for the objects deps report
        objects_deps_target = UserRequest(
            UserRequestScope.VARIANT,
            target="objects_deps",
        )

        elements.append(
            CMakeCustomTarget(
                objects_deps_target.target_name,
                "Generate objects dependencies report",
                [],
                objects_deps_cmake_cmd.outputs,
            )
        )
        # Register the generated html report as an artifact
        self.execution_context.data_registry.insert(
            ReportRelevantFiles(
                target=objects_deps_target,
                file_type=ReportRelevantFileType.HTML,
                files_to_be_included=[],
                html_content=ReportRelevantHtmlContent(
                    name="Objects Dependencies",
                    index_html=Path(objects_deps_html_rel_path),
                ),
            ),
            objects_deps_target.target_name,
        )

        return elements
