"""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"])]