from types import SimpleNamespace
from uuid import uuid4

import pytest

from src.core.exceptions import ConflictError
from src.domain.deployments.service import DeployService


class FakeDeployRepo:
    def __init__(self, active=None):
        self.active = active
        self.created = []

    async def get_active_for_project_environment(self, project_id, environment):
        return self.active

    async def create(self, project_id, revision_id, environment, created_by=None):
        row = SimpleNamespace(
            id=uuid4(), project_id=project_id, revision_id=revision_id,
            environment=environment, status="pending"
        )
        self.created.append(row)
        return row


@pytest.mark.asyncio
async def test_create_deploy_rejects_an_inflight_deployment():
    repo = FakeDeployRepo(active=SimpleNamespace(status="deploying"))
    service = DeployService(repo, domain_repo=None)

    with pytest.raises(ConflictError, match="already in progress"):
        await service.create_deploy(uuid4(), uuid4(), "production")

    assert repo.created == []


@pytest.mark.asyncio
async def test_create_deploy_allows_new_deployment_after_terminal_state():
    repo = FakeDeployRepo(active=None)
    service = DeployService(repo, domain_repo=None)

    row = await service.create_deploy(uuid4(), uuid4(), "production")

    assert row.status == "pending"
    assert len(repo.created) == 1
