"""Tests for PsService.set_commands."""

from __future__ import annotations

import pytest

from kuberoku.exceptions import AppNotFoundError
from kuberoku.factory import KuberokuFactory
from kuberoku.k8s.resources import safe_name


def test_set_single_command(deployed_factory: KuberokuFactory) -> None:
    result = deployed_factory.ps.set_commands(
        "myapp",
        {"web": "gunicorn app:app"},
        no_restart=True,
    )
    assert result["web"].command == "gunicorn app:app"
    assert result["web"].command_source == "manual"


def test_set_multiple_commands(deployed_factory: KuberokuFactory) -> None:
    deployed_factory.deploy.deploy("myapp", image="myapp:v1", process_type="worker", wait=False)
    result = deployed_factory.ps.set_commands(
        "myapp", {"web": "gunicorn", "worker": "celery"}, no_restart=True
    )
    assert result["web"].command == "gunicorn"
    assert result["worker"].command == "celery"


def test_set_patches_deployment_command(deployed_factory: KuberokuFactory) -> None:
    deployed_factory.ps.set_commands("myapp", {"web": "python app.py"}, no_restart=True)
    dep = deployed_factory.k8s.get_deployment(
        deployed_factory.namespace, safe_name(deployed_factory.prefix, "myapp", "web")
    )
    container = dep["spec"]["template"]["spec"]["containers"][0]
    assert container["command"] == ["/bin/sh", "-c", "python app.py"]


def test_set_no_deployment_ok(deployed_factory: KuberokuFactory) -> None:
    # Set command for a process type without a Deployment — should not error
    result = deployed_factory.ps.set_commands("myapp", {"newtype": "echo hi"}, no_restart=True)
    assert result["newtype"].command == "echo hi"


def test_set_creates_release(deployed_factory: KuberokuFactory) -> None:
    deployed_factory.ps.set_commands("myapp", {"web": "gunicorn"}, no_restart=True)
    releases = deployed_factory.releases.list("myapp")
    assert any("Set commands" in r.description for r in releases)


def test_set_app_not_found(deployed_factory: KuberokuFactory) -> None:
    with pytest.raises(AppNotFoundError):
        deployed_factory.ps.set_commands("nonexistent", {"web": "cmd"})


def test_set_on_step(deployed_factory: KuberokuFactory) -> None:
    steps: list[str] = []
    deployed_factory.ps.set_commands(
        "myapp", {"web": "gunicorn"}, no_restart=True, on_step=steps.append
    )
    assert len(steps) > 0


def test_no_restart_flag(deployed_factory: KuberokuFactory) -> None:
    deployed_factory.ps.set_commands("myapp", {"web": "gunicorn"}, no_restart=True)
    dep = deployed_factory.k8s.get_deployment(
        deployed_factory.namespace, safe_name(deployed_factory.prefix, "myapp", "web")
    )
    template_meta = dep.get("spec", {}).get("template", {}).get("metadata", {})
    annotations = template_meta.get("annotations", {})
    assert "kubectl.kubernetes.io/restartedAt" not in annotations


def test_restart_triggers_annotation(deployed_factory: KuberokuFactory) -> None:
    deployed_factory.ps.set_commands("myapp", {"web": "gunicorn"}, no_restart=False)
    dep = deployed_factory.k8s.get_deployment(
        deployed_factory.namespace, safe_name(deployed_factory.prefix, "myapp", "web")
    )
    template_meta = dep.get("spec", {}).get("template", {}).get("metadata", {})
    annotations = template_meta.get("annotations", {})
    assert "kubectl.kubernetes.io/restartedAt" in annotations
