"""Artifact deployment success must not be reported as full application readiness
while a required capability is blocked (e.g. the static site is live but Auth has
no cloud_auth_config). See CLAUDE.md's Core<->Cloud contract and
docs/CAPABILITY_RUNTIME_PROJECTION.md.
"""
from __future__ import annotations

from types import SimpleNamespace
from unittest.mock import AsyncMock, MagicMock
from uuid import uuid4

import pytest
from src.domain.builder.schemas import CapabilitySummary
from src.domain.builder.service import WorkspaceHydrateService


def _service(*, project_ref: str = "pabc123") -> WorkspaceHydrateService:
    project_id = uuid4()
    revision_id = uuid4()
    project_repo = MagicMock()
    project_repo.get_by_id = AsyncMock(
        return_value=SimpleNamespace(id=project_id, project_ref=project_ref, slug="demo")
    )

    deploy_repo = MagicMock()
    deploy_repo.list_for_project = AsyncMock(
        return_value=[SimpleNamespace(id=uuid4(), status="live", revision_id=revision_id)]
    )

    domain_repo = MagicMock()
    domain_repo.list_for_project = AsyncMock(
        return_value=[
            SimpleNamespace(
                domain="demo.example.com", is_primary=True, verification_status="verified"
            )
        ]
    )

    service = WorkspaceHydrateService(
        **{
            name: MagicMock()
            for name in [
                "project_repo", "revision_repo", "codegen_repo", "prompt_session_repo",
                "prompt_repo", "run_chat_repo", "preview_repo", "manifest_repo",
                "deploy_repo", "domain_repo", "timeline_repo", "changed_file_repo",
            ]
        }
    )
    service._project_repo = project_repo
    service._deploy_repo = deploy_repo
    service._domain_repo = domain_repo
    return service, project_id, revision_id


@pytest.mark.asyncio
async def test_fully_deployed_and_ready_has_no_blockers():
    service, project_id, revision_id = _service()

    summary = await service._build_publish_summary(
        project_id, revision_id, {"auth": CapabilitySummary(status="ready")}
    )

    assert summary.publish_blockers == []


@pytest.mark.asyncio
async def test_artifact_deployed_but_blocked_capability_blocks_application_readiness():
    service, project_id, revision_id = _service()

    summary = await service._build_publish_summary(
        project_id,
        revision_id,
        {
            "auth": CapabilitySummary(status="blocked", reason="not_declared"),
            "forms": CapabilitySummary(status="ready"),
        },
    )

    # The artifact's own deploy/domain state is still fully healthy...
    assert summary.deploy_status == "live"
    # ...but application readiness must reflect the blocked capability, not just
    # the artifact.
    assert "capability_blocked:auth" in summary.publish_blockers
    assert "capability_blocked:forms" not in summary.publish_blockers


@pytest.mark.asyncio
async def test_declared_or_ready_capabilities_never_block_readiness():
    service, project_id, revision_id = _service()

    summary = await service._build_publish_summary(
        project_id,
        revision_id,
        {
            "auth": CapabilitySummary(status="declared"),
            "forms": CapabilitySummary(status="ready"),
            "feature_packs": CapabilitySummary(status="shadow"),
        },
    )

    assert summary.publish_blockers == []


@pytest.mark.asyncio
async def test_no_capabilities_argument_is_backward_compatible():
    service, project_id, revision_id = _service()

    summary = await service._build_publish_summary(project_id, revision_id)

    assert summary.publish_blockers == []
