from __future__ import annotations

from pathlib import Path
from types import SimpleNamespace

from terminaluse.lib.cli.commands.deploy import deploy


def test_deploy_sends_source_snapshot_id_when_building(monkeypatch, tmp_path: Path) -> None:
    config_path = tmp_path / "config.yaml"
    config_path.write_text("agent:\n  name: acme/test-agent\n", encoding="utf-8")

    deploy_calls: list[dict] = []

    raw_response = SimpleNamespace(
        data=SimpleNamespace(agent_id="agent_123", version_id="version_123"),
        headers={},
    )

    client = SimpleNamespace(
        namespaces=SimpleNamespace(retrieve_by_slug=lambda namespace: SimpleNamespace(id="ns_1", slug=namespace)),
        registry=SimpleNamespace(
            auth=lambda namespace: SimpleNamespace(
                registry_url="gcr.io",
                repository="repo",
                username="user",
                token="token",
            )
        ),
        agents=SimpleNamespace(
            environments=SimpleNamespace(resolve_env=lambda **_: (_ for _ in ()).throw(Exception("no env yet"))),
            with_raw_response=SimpleNamespace(deploy=lambda **kwargs: deploy_calls.append(kwargs) or raw_response),
        ),
    )

    monkeypatch.setattr(
        "terminaluse.lib.cli.utils.client.get_authenticated_client",
        lambda: client,
    )
    monkeypatch.setattr(
        "terminaluse.lib.sdk.config.agent_manifest.AgentManifest.from_yaml",
        lambda _: SimpleNamespace(
            agent=SimpleNamespace(
                name="acme/test-agent",
                namespace_slug="acme",
                short_name="test-agent",
                sdk_type="claude_agent_sdk",
            ),
            deployment=None,
        ),
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.utils.git_utils.detect_git_info",
        lambda _: SimpleNamespace(
            is_git_repo=True,
            branch="feature/foo",
            commit_hash="abc1234",
            commit_message="Deploy commit",
            is_dirty=False,
        ),
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.utils.git_utils.detect_git_author",
        lambda _: SimpleNamespace(name="Test Author", email="test@example.com"),
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.utils.git_utils.generate_image_tag",
        lambda _: "image-tag",
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.utils.credentials.get_stored_credentials",
        lambda: None,
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.handlers.deploy_handlers.build_deploy_config",
        lambda env_config, is_production: {
            "replicas": 2,
            "resources": None,
            "are_tasks_sticky": False,
        },
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.handlers.deploy_handlers.check_dockerfile_exists",
        lambda _config_path: True,
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.handlers.source_snapshot_handlers.capture_deploy_source_snapshot",
        lambda **_: SimpleNamespace(filesystem_id="fs_source"),
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.handlers.remote_build_handlers.remote_build_enabled",
        lambda: True,
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.handlers.remote_build_handlers.remote_build_image",
        lambda **_: "gcr.io/repo/acme/test-agent:image-tag",
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.commands.deploy.console.print",
        lambda *args, **kwargs: None,
    )

    deploy(
        config=str(config_path),
        branch=None,
        skip_build=False,
        yes=True,
        detach=True,
    )

    assert len(deploy_calls) == 1
    assert deploy_calls[0]["agent_name"] == "acme/test-agent"
    assert deploy_calls[0]["branch"] == "feature/foo"
    assert deploy_calls[0]["source_filesystem_id"] == "fs_source"


def test_deploy_does_not_capture_source_snapshot_when_skipping_build(monkeypatch, tmp_path: Path) -> None:
    config_path = tmp_path / "config.yaml"
    config_path.write_text("agent:\n  name: acme/test-agent\n", encoding="utf-8")

    deploy_calls: list[dict] = []
    capture_calls: list[dict] = []

    raw_response = SimpleNamespace(
        data=SimpleNamespace(agent_id="agent_123", version_id="version_123"),
        headers={},
    )

    client = SimpleNamespace(
        namespaces=SimpleNamespace(retrieve_by_slug=lambda namespace: SimpleNamespace(id="ns_1", slug=namespace)),
        registry=SimpleNamespace(
            auth=lambda namespace: SimpleNamespace(
                registry_url="gcr.io",
                repository="repo",
                username="user",
                token="token",
            )
        ),
        agents=SimpleNamespace(
            environments=SimpleNamespace(resolve_env=lambda **_: (_ for _ in ()).throw(Exception("no env yet"))),
            with_raw_response=SimpleNamespace(deploy=lambda **kwargs: deploy_calls.append(kwargs) or raw_response),
        ),
    )

    monkeypatch.setattr(
        "terminaluse.lib.cli.utils.client.get_authenticated_client",
        lambda: client,
    )
    monkeypatch.setattr(
        "terminaluse.lib.sdk.config.agent_manifest.AgentManifest.from_yaml",
        lambda _: SimpleNamespace(
            agent=SimpleNamespace(
                name="acme/test-agent",
                namespace_slug="acme",
                short_name="test-agent",
                sdk_type="claude_agent_sdk",
            ),
            deployment=None,
        ),
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.utils.git_utils.detect_git_info",
        lambda _: SimpleNamespace(
            is_git_repo=True,
            branch="feature/foo",
            commit_hash="abc1234",
            commit_message="Deploy commit",
            is_dirty=False,
        ),
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.utils.git_utils.detect_git_author",
        lambda _: SimpleNamespace(name="Test Author", email="test@example.com"),
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.utils.git_utils.generate_image_tag",
        lambda _: "image-tag",
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.utils.credentials.get_stored_credentials",
        lambda: None,
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.handlers.deploy_handlers.build_deploy_config",
        lambda env_config, is_production: {
            "replicas": 2,
            "resources": None,
            "are_tasks_sticky": False,
        },
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.handlers.source_snapshot_handlers.capture_deploy_source_snapshot",
        lambda **kwargs: capture_calls.append(kwargs) or SimpleNamespace(filesystem_id="fs_source"),
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.handlers.remote_build_handlers.remote_build_enabled",
        lambda: True,
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.handlers.remote_build_handlers.remote_build_image",
        lambda **_: "gcr.io/repo/acme/test-agent:image-tag",
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.commands.deploy.console.print",
        lambda *args, **kwargs: None,
    )

    deploy(
        config=str(config_path),
        branch=None,
        skip_build=True,
        yes=True,
        detach=True,
    )

    assert capture_calls == []
    assert len(deploy_calls) == 1
    assert deploy_calls[0]["source_filesystem_id"] is None


def test_deploy_continues_when_source_snapshot_capture_fails(monkeypatch, tmp_path: Path) -> None:
    config_path = tmp_path / "config.yaml"
    config_path.write_text("agent:\n  name: acme/test-agent\n", encoding="utf-8")

    deploy_calls: list[dict] = []
    console_messages: list[str] = []

    raw_response = SimpleNamespace(
        data=SimpleNamespace(agent_id="agent_123", version_id="version_123"),
        headers={},
    )

    client = SimpleNamespace(
        namespaces=SimpleNamespace(retrieve_by_slug=lambda namespace: SimpleNamespace(id="ns_1", slug=namespace)),
        registry=SimpleNamespace(
            auth=lambda namespace: SimpleNamespace(
                registry_url="gcr.io",
                repository="repo",
                username="user",
                token="token",
            )
        ),
        agents=SimpleNamespace(
            environments=SimpleNamespace(resolve_env=lambda **_: (_ for _ in ()).throw(Exception("no env yet"))),
            with_raw_response=SimpleNamespace(deploy=lambda **kwargs: deploy_calls.append(kwargs) or raw_response),
        ),
    )

    monkeypatch.setattr(
        "terminaluse.lib.cli.utils.client.get_authenticated_client",
        lambda: client,
    )
    monkeypatch.setattr(
        "terminaluse.lib.sdk.config.agent_manifest.AgentManifest.from_yaml",
        lambda _: SimpleNamespace(
            agent=SimpleNamespace(
                name="acme/test-agent",
                namespace_slug="acme",
                short_name="test-agent",
                sdk_type="claude_agent_sdk",
            ),
            deployment=None,
        ),
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.utils.git_utils.detect_git_info",
        lambda _: SimpleNamespace(
            is_git_repo=True,
            branch="feature/foo",
            commit_hash="abc1234",
            commit_message="Deploy commit",
            is_dirty=False,
        ),
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.utils.git_utils.detect_git_author",
        lambda _: SimpleNamespace(name="Test Author", email="test@example.com"),
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.utils.git_utils.generate_image_tag",
        lambda _: "image-tag",
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.utils.credentials.get_stored_credentials",
        lambda: None,
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.handlers.deploy_handlers.build_deploy_config",
        lambda env_config, is_production: {
            "replicas": 2,
            "resources": None,
            "are_tasks_sticky": False,
        },
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.handlers.deploy_handlers.check_dockerfile_exists",
        lambda _config_path: True,
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.handlers.source_snapshot_handlers.capture_deploy_source_snapshot",
        lambda **_: (_ for _ in ()).throw(RuntimeError("snapshot failure")),
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.handlers.remote_build_handlers.remote_build_enabled",
        lambda: True,
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.handlers.remote_build_handlers.remote_build_image",
        lambda **_: "gcr.io/repo/acme/test-agent:image-tag",
    )
    monkeypatch.setattr(
        "terminaluse.lib.cli.commands.deploy.console.print",
        lambda *args, **kwargs: console_messages.append(" ".join(str(arg) for arg in args)),
    )

    deploy(
        config=str(config_path),
        branch=None,
        skip_build=False,
        yes=True,
        detach=True,
    )

    assert len(deploy_calls) == 1
    assert deploy_calls[0]["source_filesystem_id"] is None
    assert any("Could not capture source snapshot for Builder reopenability" in message for message in console_messages)
