"""Tests for Procfile integration in deploy."""

from __future__ import annotations

from pathlib import Path

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


def test_procfile_creates_process_types(app_factory: KuberokuFactory, tmp_path: Path) -> None:
    procfile = tmp_path / "Procfile"
    procfile.write_text("web: python app.py\nworker: celery -A tasks\n")
    release = app_factory.deploy.deploy(
        "myapp", image="myapp:v1", procfile_path=procfile, wait=False
    )
    assert "web" in release.images
    assert "worker" in release.images


def test_procfile_sets_commands(app_factory: KuberokuFactory, tmp_path: Path) -> None:
    procfile = tmp_path / "Procfile"
    procfile.write_text("web: gunicorn app:app\n")
    app_factory.deploy.deploy("myapp", image="myapp:v1", procfile_path=procfile, wait=False)
    dep = app_factory.k8s.get_deployment(
        app_factory.namespace, safe_name(app_factory.prefix, "myapp", "web")
    )
    container = dep["spec"]["template"]["spec"]["containers"][0]
    assert container["command"] == ["/bin/sh", "-c", "gunicorn app:app"]


def test_procfile_command_source_is_procfile(app_factory: KuberokuFactory, tmp_path: Path) -> None:
    procfile = tmp_path / "Procfile"
    procfile.write_text("web: gunicorn app:app\n")
    release = app_factory.deploy.deploy(
        "myapp", image="myapp:v1", procfile_path=procfile, wait=False
    )
    assert release.formation["web"].command_source == "procfile"


def test_procfile_skips_manual_overrides(app_factory: KuberokuFactory, tmp_path: Path) -> None:
    # First deploy with Procfile
    procfile = tmp_path / "Procfile"
    procfile.write_text("web: gunicorn app:app\n")
    app_factory.deploy.deploy("myapp", image="myapp:v1", procfile_path=procfile, wait=False)
    # Manual override
    app_factory.ps.set_commands("myapp", {"web": "custom-cmd"}, no_restart=True)
    # Redeploy with Procfile — should keep manual command
    release = app_factory.deploy.deploy(
        "myapp", image="myapp:v2", procfile_path=procfile, wait=False
    )
    assert release.formation["web"].command == "custom-cmd"
    assert release.formation["web"].command_source == "manual"


def test_no_procfile_flag(app_factory: KuberokuFactory, tmp_path: Path) -> None:
    procfile = tmp_path / "Procfile"
    procfile.write_text("web: gunicorn app:app\nworker: celery\n")
    release = app_factory.deploy.deploy(
        "myapp", image="myapp:v1", procfile_path=procfile, no_procfile=True, wait=False
    )
    # Only default "web" should exist, no worker from Procfile
    assert "worker" not in release.images


def test_no_procfile_file_ok(app_factory: KuberokuFactory, tmp_path: Path) -> None:
    missing = tmp_path / "Procfile"
    release = app_factory.deploy.deploy(
        "myapp", image="myapp:v1", procfile_path=missing, wait=False
    )
    assert "web" in release.images


def test_procfile_new_type_auto_creates(app_factory: KuberokuFactory, tmp_path: Path) -> None:
    # First deploy creates only web
    app_factory.deploy.deploy("myapp", image="myapp:v1", wait=False)
    # Add worker via Procfile
    procfile = tmp_path / "Procfile"
    procfile.write_text("web: python app.py\nworker: celery\n")
    release = app_factory.deploy.deploy(
        "myapp", image="myapp:v2", procfile_path=procfile, wait=False
    )
    assert "worker" in release.images
    dep = app_factory.k8s.get_deployment(
        app_factory.namespace, safe_name(app_factory.prefix, "myapp", "worker")
    )
    assert dep["spec"]["template"]["spec"]["containers"][0]["image"] == "myapp:v2"


def test_procfile_updates_existing_procfile_entries(
    app_factory: KuberokuFactory, tmp_path: Path
) -> None:
    procfile = tmp_path / "Procfile"
    procfile.write_text("web: python app.py\n")
    app_factory.deploy.deploy("myapp", image="myapp:v1", procfile_path=procfile, wait=False)
    # Update Procfile command
    procfile.write_text("web: gunicorn app:app\n")
    release = app_factory.deploy.deploy(
        "myapp", image="myapp:v2", procfile_path=procfile, wait=False
    )
    assert release.formation["web"].command == "gunicorn app:app"
