from __future__ import annotations

import re
import zipfile
from pathlib import Path
from subprocess import check_call
from tempfile import TemporaryDirectory
from typing import TYPE_CHECKING

import pytest

if TYPE_CHECKING:
    from collections.abc import Iterator


@pytest.fixture
def built_wheel() -> Iterator[Path]:
    with TemporaryDirectory() as tmp_dir:
        dist_dir = Path(tmp_dir)
        meta_dir = Path(__file__).parent.parent
        check_call(["uv", "build", "--wheel", str(meta_dir), "--out-dir", str(dist_dir)], cwd=meta_dir)
        wheels = list(dist_dir.glob("tox_uv-*.whl"))
        assert len(wheels) == 1
        yield wheels[0]


def test_version_injected_into_dependency(built_wheel: Path) -> None:
    with zipfile.ZipFile(built_wheel) as whl:
        metadata_files = [name for name in whl.namelist() if name.endswith("/METADATA")]
        assert len(metadata_files) == 1
        metadata = whl.read(metadata_files[0]).decode()

    version_match = re.search(r"^Version: (.+)$", metadata, re.MULTILINE)
    assert version_match is not None
    version = version_match.group(1)

    bare_dep_match = re.search(r"^Requires-Dist: tox-uv-bare==(.+)$", metadata, re.MULTILINE)
    assert bare_dep_match is not None
    bare_version = bare_dep_match.group(1)

    assert version == bare_version


def test_uv_dependency_present(built_wheel: Path) -> None:
    with zipfile.ZipFile(built_wheel) as whl:
        metadata_files = [name for name in whl.namelist() if name.endswith("/METADATA")]
        metadata = whl.read(metadata_files[0]).decode()

    assert re.search(r"^Requires-Dist: uv<1,>=0\.9\.27$", metadata, re.MULTILINE) is not None


def test_wheel_contains_placeholder_module(built_wheel: Path) -> None:
    with zipfile.ZipFile(built_wheel) as whl:
        assert "tox_uv_meta/__init__.py" in whl.namelist()


def test_wheel_does_not_contain_tox_uv_package(built_wheel: Path) -> None:
    with zipfile.ZipFile(built_wheel) as whl:
        tox_uv_files = [name for name in whl.namelist() if name.startswith("tox_uv/")]
        assert not tox_uv_files, f"Meta package should not contain tox_uv package, found: {tox_uv_files}"


def test_build_hook_updates_metadata() -> None:
    from meta.hatch_build import CustomMetadataHook  # noqa: PLC0415

    hook = CustomMetadataHook("test", {})
    metadata: dict[str, object] = {
        "version": "1.2.3",
        "dependencies": ["tox-uv-bare", "uv<1,>=0.9.27"],
    }
    hook.update(metadata)

    assert metadata["dependencies"] == ["tox-uv-bare==1.2.3", "uv<1,>=0.9.27"]


def test_build_hook_preserves_other_dependencies() -> None:
    from meta.hatch_build import CustomMetadataHook  # noqa: PLC0415

    hook = CustomMetadataHook("test", {})
    metadata: dict[str, object] = {
        "version": "2.0.0",
        "dependencies": ["other-package>=1.0", "tox-uv-bare", "another-dep"],
    }
    hook.update(metadata)

    assert metadata["dependencies"] == ["other-package>=1.0", "tox-uv-bare==2.0.0", "another-dep"]


def test_build_hook_injects_root_readme() -> None:
    from meta.hatch_build import CustomMetadataHook  # noqa: PLC0415

    hook = CustomMetadataHook("test", {})
    metadata: dict[str, object] = {"version": "1.0.0", "dependencies": []}
    hook.update(metadata)

    readme = metadata["readme"]
    assert isinstance(readme, dict)
    assert readme["content-type"] == "text/markdown"
    assert readme["text"] == (Path(__file__).parents[2] / "README.md").read_text()


def test_wheel_contains_root_readme(built_wheel: Path) -> None:
    with zipfile.ZipFile(built_wheel) as whl:
        metadata_files = [name for name in whl.namelist() if name.endswith("/METADATA")]
        metadata = whl.read(metadata_files[0]).decode()

    root_readme = (Path(__file__).parents[2] / "README.md").read_text()
    assert root_readme in metadata
