# #region ReportBuilder [C:5] [TYPE Module] [SEMANTICS report, clean-release, compliance, builder, render]
# @BRIEF Build and persist compliance reports with consistent counter invariants.
# @LAYER Domain
# @RELATION DEPENDS_ON -> [CleanReleaseModels]
# @RELATION DEPENDS_ON -> [RepositoryRelations]
# @INVARIANT  blocking_violations_count never exceeds violations_count.
# @TEST_CONTRACT  ComplianceCheckRun,List[ComplianceViolation] -> ComplianceReport
# @TEST_FIXTURE  blocked_with_two_violations -> file:backend/tests/fixtures/clean_release/fixtures_clean_release.json
# @TEST_EDGE  empty_violations_for_blocked -> BLOCKED run with zero blocking violations raises ValueError
# @TEST_EDGE  counter_mismatch -> blocking counter cannot exceed total violations counter
# @TEST_EDGE  missing_operator_summary -> non-terminal run prevents report creation and summary generation
# @TEST_INVARIANT  blocking_count_le_total_count -> VERIFIED_BY: [counter_mismatch, empty_violations_for_blocked]
# @DATA_CONTRACT  Input[ComplianceRun, List[ComplianceViolation]] -> Output[ComplianceReport]
# @PRE  Compliance run is terminal and repository persistence is available for report storage.
# @POST  Returns immutable report payloads with consistent violation counters and operator summary content.
# @SIDE_EFFECT  Writes report artifacts to repository when persistence helpers are invoked.

from __future__ import annotations

from datetime import UTC, datetime
from uuid import uuid4

from ...models.clean_release import ComplianceReport, ComplianceRun, ComplianceViolation
from .enums import ComplianceDecision, RunStatus
from .repository import CleanReleaseRepository


class ComplianceReportBuilder:
    def __init__(self, repository: CleanReleaseRepository):
        self.repository = repository

    def build_report_payload(
        self, check_run: ComplianceRun, violations: list[ComplianceViolation]
    ) -> ComplianceReport:
        if check_run.status == RunStatus.RUNNING:
            raise ValueError("Cannot build report for non-terminal run")

        violations_count = len(violations)
        blocking_violations_count = sum(
            1
            for v in violations
            if bool(getattr(v, "blocked_release", False))
            or bool(getattr(v, "evidence_json", {}).get("blocked_release", False))
        )

        if (
            check_run.final_status == ComplianceDecision.BLOCKED
            and blocking_violations_count <= 0
        ):
            raise ValueError("Blocked run requires at least one blocking violation")

        summary = (
            "Compliance passed with no blocking violations"
            if check_run.final_status == ComplianceDecision.PASSED
            else f"Blocked with {blocking_violations_count} blocking violation(s)"
        )

        return ComplianceReport(
            id=f"CCR-{uuid4()}",
            run_id=check_run.id,
            candidate_id=check_run.candidate_id,
            generated_at=datetime.now(UTC),
            final_status=check_run.final_status,
            summary_json={
                "operator_summary": summary,
                "violations_count": violations_count,
                "blocking_violations_count": blocking_violations_count,
            },
            immutable=True,
        )

    def persist_report(self, report: ComplianceReport) -> ComplianceReport:
        return self.repository.save_report(report)


# #endregion ReportBuilder
