# #region clean_release_facade [C:3] [TYPE Module] [SEMANTICS clean-release, facade, orchestration, repository, crud]
# @BRIEF Unified entry point for clean release operations.
# @LAYER Application
# @RELATION DEPENDS_ON -> ComplianceOrchestrator


from src.core.config_manager import ConfigManager
from src.core.logger import belief_scope
from src.models.clean_release import CleanPolicySnapshot, SourceRegistrySnapshot
from src.services.clean_release.dto import CandidateOverviewDTO
from src.services.clean_release.enums import CandidateStatus, ComplianceDecision, RunStatus
from src.services.clean_release.repositories import ApprovalRepository, ArtifactRepository, AuditRepository, CandidateRepository, ComplianceRepository, ManifestRepository, PolicyRepository, PublicationRepository, ReportRepository


class CleanReleaseFacade:
    """
    @PURPOSE: Orchestrates repositories and services to provide a clean API for UI/CLI.
    """
    def __init__(
        self,
        candidate_repo: CandidateRepository,
        artifact_repo: ArtifactRepository,
        manifest_repo: ManifestRepository,
        policy_repo: PolicyRepository,
        compliance_repo: ComplianceRepository,
        report_repo: ReportRepository,
        approval_repo: ApprovalRepository,
        publication_repo: PublicationRepository,
        audit_repo: AuditRepository,
        config_manager: ConfigManager
    ):
        self.candidate_repo = candidate_repo
        self.artifact_repo = artifact_repo
        self.manifest_repo = manifest_repo
        self.policy_repo = policy_repo
        self.compliance_repo = compliance_repo
        self.report_repo = report_repo
        self.approval_repo = approval_repo
        self.publication_repo = publication_repo
        self.audit_repo = audit_repo
        self.config_manager = config_manager

    def resolve_active_policy_snapshot(self) -> CleanPolicySnapshot | None:
        """
        @PURPOSE: Resolve the active policy snapshot based on ConfigManager.
        """
        with belief_scope("CleanReleaseFacade.resolve_active_policy_snapshot"):
            config = self.config_manager.get_config()
            policy_id = config.settings.clean_release.active_policy_id
            if not policy_id:
                return None
            return self.policy_repo.get_policy_snapshot(policy_id)

    def resolve_active_registry_snapshot(self) -> SourceRegistrySnapshot | None:
        """
        @PURPOSE: Resolve the active registry snapshot based on ConfigManager.
        """
        with belief_scope("CleanReleaseFacade.resolve_active_registry_snapshot"):
            config = self.config_manager.get_config()
            registry_id = config.settings.clean_release.active_registry_id
            if not registry_id:
                return None
            return self.policy_repo.get_registry_snapshot(registry_id)

    def get_candidate_overview(self, candidate_id: str) -> CandidateOverviewDTO | None:
        """
        @PURPOSE: Build a comprehensive overview for a candidate.
        """
        with belief_scope("CleanReleaseFacade.get_candidate_overview"):
            candidate = self.candidate_repo.get_by_id(candidate_id)
            if not candidate:
                return None

            manifest = self.manifest_repo.get_latest_for_candidate(candidate_id)
            runs = self.compliance_repo.list_runs_by_candidate(candidate_id)
            latest_run = runs[-1] if runs else None

            report = None
            if latest_run:
                report = self.report_repo.get_by_run(latest_run.id)

            approval = self.approval_repo.get_latest_for_candidate(candidate_id)
            publication = self.publication_repo.get_latest_for_candidate(candidate_id)

            active_policy = self.resolve_active_policy_snapshot()
            active_registry = self.resolve_active_registry_snapshot()

            return CandidateOverviewDTO(
                candidate_id=candidate.id,
                version=candidate.version,
                source_snapshot_ref=candidate.source_snapshot_ref,
                status=CandidateStatus(candidate.status),
                latest_manifest_id=manifest.id if manifest else None,
                latest_manifest_digest=manifest.manifest_digest if manifest else None,
                latest_run_id=latest_run.id if latest_run else None,
                latest_run_status=RunStatus(latest_run.status) if latest_run else None,
                latest_report_id=report.id if report else None,
                latest_report_final_status=ComplianceDecision(report.final_status) if report else None,
                latest_policy_snapshot_id=active_policy.id if active_policy else None,
                latest_policy_version=active_policy.policy_version if active_policy else None,
                latest_registry_snapshot_id=active_registry.id if active_registry else None,
                latest_registry_version=active_registry.registry_version if active_registry else None,
                latest_approval_decision=approval.decision if approval else None,
                latest_publication_id=publication.id if publication else None,
                latest_publication_status=publication.status if publication else None
            )

    def list_candidates(self) -> list[CandidateOverviewDTO]:
        """
        @PURPOSE: List all candidates with their current status.
        """
        with belief_scope("CleanReleaseFacade.list_candidates"):
            candidates = self.candidate_repo.list_all()
            return [self.get_candidate_overview(c.id) for c in candidates]

# #endregion clean_release_facade
