# [DEF:backend.src.services.clean_release.stages.manifest_consistency:Module]
# @TIER: STANDARD
# @SEMANTICS: clean-release, compliance-stage, manifest, consistency, digest
# @PURPOSE: Ensure run is bound to the exact manifest snapshot and digest used at run creation time.
# @LAYER: Domain
# @RELATION: IMPLEMENTS -> backend.src.services.clean_release.stages.base.ComplianceStage
# @RELATION: DEPENDS_ON -> backend.src.services.clean_release.stages.base
# @INVARIANT: Digest mismatch between run and manifest yields ERROR with blocking violation evidence.

from __future__ import annotations

from ....core.logger import belief_scope, logger
from ..enums import ComplianceDecision, ComplianceStageName, ViolationSeverity
from .base import ComplianceStageContext, StageExecutionResult, build_violation


# [DEF:ManifestConsistencyStage:Class]
# @PURPOSE: Validate run/manifest linkage consistency.
# @PRE: context.run and context.manifest are loaded from repository for same run.
# @POST: Returns PASSED when digests match, otherwise ERROR with one violation.
class ManifestConsistencyStage:
    stage_name = ComplianceStageName.MANIFEST_CONSISTENCY

    def execute(self, context: ComplianceStageContext) -> StageExecutionResult:
        with belief_scope("ManifestConsistencyStage.execute"):
            expected_digest = str(context.run.manifest_digest or "").strip()
            actual_digest = str(context.manifest.manifest_digest or "").strip()

            logger.reason(
                f"Manifest consistency evaluation run={context.run.id} manifest={context.manifest.id} "
                f"expected_digest={expected_digest} actual_digest={actual_digest}"
            )

            if expected_digest and expected_digest == actual_digest:
                return StageExecutionResult(
                    decision=ComplianceDecision.PASSED,
                    details_json={
                        "manifest_id": context.manifest.id,
                        "manifest_digest": actual_digest,
                        "consistent": True,
                    },
                    violations=[],
                )

            violation = build_violation(
                run_id=context.run.id,
                stage_name=self.stage_name,
                code="MANIFEST_DIGEST_MISMATCH",
                message="Run manifest digest does not match resolved manifest snapshot",
                severity=ViolationSeverity.CRITICAL,
                evidence_json={
                    "manifest_id": context.manifest.id,
                    "run_manifest_digest": expected_digest,
                    "actual_manifest_digest": actual_digest,
                },
                blocked_release=True,
            )
            return StageExecutionResult(
                decision=ComplianceDecision.ERROR,
                details_json={
                    "manifest_id": context.manifest.id,
                    "run_manifest_digest": expected_digest,
                    "actual_manifest_digest": actual_digest,
                    "consistent": False,
                },
                violations=[violation],
            )
# [/DEF:ManifestConsistencyStage:Class]

# [/DEF:backend.src.services.clean_release.stages.manifest_consistency:Module]