from __future__ import annotations

import json
import os
from pathlib import Path
import subprocess
import sys
import tempfile
import unittest
import tomllib


ROOT = Path(__file__).resolve().parents[1]
SCRIPT = ROOT / "scripts" / "release_metadata.py"


class ReleaseMetadataTests(unittest.TestCase):
    def _project_version(self) -> str:
        with (ROOT / "pyproject.toml").open("rb") as handle:
            pyproject = tomllib.load(handle)
        return pyproject["project"]["version"]

    def _run(self, *args: str) -> subprocess.CompletedProcess[str]:
        with tempfile.TemporaryDirectory() as tmp_dir:
            shim_dir = Path(tmp_dir)
            python_shim = shim_dir / "python"
            python_shim.symlink_to(sys.executable)

            env = os.environ.copy()
            env["PATH"] = f"{shim_dir}{os.pathsep}{env.get('PATH', '')}"

            return subprocess.run(
                ["python", str(SCRIPT), *args],
                cwd=ROOT,
                capture_output=True,
                text=True,
                env=env,
            )

    def test_version_prints_project_version(self) -> None:
        version = self._project_version()
        completed = self._run("--version")
        self.assertEqual(completed.returncode, 0, completed.stderr)
        self.assertEqual(completed.stdout.strip(), version)

    def test_assert_tag_json_includes_version_and_tag(self) -> None:
        version = self._project_version()
        expected_tag = f"v{version}"

        completed = self._run("--assert-tag", expected_tag, "--json")
        self.assertEqual(completed.returncode, 0, completed.stderr)

        payload = json.loads(completed.stdout)
        self.assertEqual(payload["version"], version)
        self.assertEqual(payload["tag"], expected_tag)

    def test_assert_tag_rejects_mismatch(self) -> None:
        completed = self._run("--assert-tag", "v9.9.9")
        self.assertEqual(completed.returncode, 1)
        self.assertEqual(completed.stdout, "")
        self.assertIn("Tag mismatch", completed.stderr)
        self.assertIn("v9.9.9", completed.stderr)


if __name__ == "__main__":
    unittest.main()
