"""Tests for the per-version pytest action script."""

from __future__ import annotations

import importlib.util
import sys
from pathlib import Path
from types import ModuleType

import pytest


def _load_script() -> ModuleType:
    path = Path(__file__).resolve().parent / "pytest_version.py"
    spec = importlib.util.spec_from_file_location("pytest_version_script", path)
    assert spec is not None and spec.loader is not None
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module


def test_run_syncs_temp_env_then_pytest(monkeypatch: pytest.MonkeyPatch) -> None:
    module = _load_script()
    commands: list[list[str]] = []
    envs: list[dict[str, str]] = []

    class _Proc:
        def __init__(self, returncode: int) -> None:
            self.returncode = returncode

    def fake_run(cmd: list[str], **kwargs: object) -> _Proc:
        commands.append(list(cmd))
        env = kwargs["env"]
        assert isinstance(env, dict)
        envs.append({str(key): str(value) for key, value in env.items()})
        return _Proc(0)

    monkeypatch.setattr(module.subprocess, "run", fake_run)
    assert module.run("3.12", ["-k", "foo"]) == 0
    assert commands[0] == ["uv", "sync", "--all-packages", "--python", "3.12"]
    assert commands[1] == ["uv", "run", "--python", "3.12", "pytest", ".", "-k", "foo"]
    assert "VIRTUAL_ENV" not in envs[0]
    assert envs[0]["UV_PROJECT_ENVIRONMENT"].endswith(".venv")
    assert envs[0]["UV_PROJECT_ENVIRONMENT"] == envs[1]["UV_PROJECT_ENVIRONMENT"]


def test_run_stops_when_sync_fails(monkeypatch: pytest.MonkeyPatch) -> None:
    module = _load_script()
    commands: list[list[str]] = []

    class _Proc:
        returncode = 4

    def fake_run(cmd: list[str], **kwargs: object) -> _Proc:
        del kwargs
        commands.append(list(cmd))
        return _Proc()

    monkeypatch.setattr(module.subprocess, "run", fake_run)
    assert module.run("3.11", []) == 4
    assert len(commands) == 1


def test_main_requires_version(monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]) -> None:
    module = _load_script()
    monkeypatch.setattr(sys, "argv", ["pytest_version.py"])
    assert module.main() == 2
    assert "usage:" in capsys.readouterr().err


def test_main_forwards_pytest_args(monkeypatch: pytest.MonkeyPatch) -> None:
    module = _load_script()
    seen: list[tuple[str, list[str]]] = []

    def fake_run(version: str, pytest_args: list[str]) -> int:
        seen.append((version, pytest_args))
        return 0

    monkeypatch.setattr(module, "run", fake_run)
    monkeypatch.setattr(sys, "argv", ["pytest_version.py", "3.14", "-q"])
    assert module.main() == 0
    assert seen == [("3.14", ["-q"])]