"""Feature inventory reads the selected dependency tree, not the builder."""
import json
import os
from pathlib import Path
import subprocess
import sys

import packaging
import pytest

import pm.extras as extras
import pm.features as features
from pm.environments import site_packages


def test_inventory_uses_the_target_and_requires_every_anchor(tmp_path, monkeypatch):
    target_root = tmp_path / "target"
    subprocess.run(
        [sys.executable, "-m", "venv", "--without-pip", str(target_root)],
        capture_output=True, check=True, timeout=60,
    )
    target = target_root / ("Scripts/python.exe" if os.name == "nt" else "bin/python")
    dependencies = tmp_path / "dependencies"
    site = site_packages(dependencies)
    site.mkdir(parents=True)
    witness = tmp_path / "child.json"
    package = site / "inventory_anchor"
    package.mkdir()
    (package / "__init__.py").write_text(
        "import json, pathlib, sys\n"
        f"pathlib.Path({str(witness)!r}).write_text(json.dumps(sys.executable), encoding='utf-8')\n",
        encoding="utf-8",
    )
    (package / "present.py").write_text("VALUE = 'target'\n", encoding="utf-8")
    (site / "one_part.py").write_text("", encoding="utf-8")
    editable = tmp_path / "editable"
    editable.mkdir()
    (editable / "editable_anchor.py").write_text("", encoding="utf-8")
    (site / "editable.pth").write_text(str(editable) + "\n", encoding="utf-8")
    launches = tmp_path / "launches.jsonl"
    (site / "launches.pth").write_text(
        f"import json, pathlib, sys; p = pathlib.Path({str(launches)!r}); "
        "text = p.read_text(encoding='utf-8') if p.exists() else ''; "
        "p.write_text(text + json.dumps(sys.executable) + '\\n', encoding='utf-8')\n",
        encoding="utf-8",
    )
    mapping = {
        "complete": "inventory_anchor.present",
        "partial": ("one_part", "absent_part"),
        "host-only": "packaging",
        "editable": "editable_anchor",
    }
    repo = tmp_path / "source"
    repo.mkdir()
    (repo / "pyproject.toml").write_text(
        "[project.optional-dependencies]\n" + "".join(f'"{name}"=[]\n' for name in mapping),
        encoding="utf-8",
    )
    monkeypatch.setattr(extras, "ANCHORS", mapping)
    before_path = list(sys.path)
    before_env = dict(os.environ)
    assert packaging.__file__ and "packaging" in sys.modules
    result = features.installed_extras(repo, dependencies, python_exe=target)
    assert result == ["complete", "editable"]
    assert Path(json.loads(witness.read_text(encoding="utf-8"))) == target
    assert [Path(json.loads(line)) for line in launches.read_text(encoding="utf-8").splitlines()] == [target]
    assert "inventory_anchor" not in sys.modules
    assert sys.path == before_path
    assert dict(os.environ) == before_env

    (site / "absent_part.py").write_text("", encoding="utf-8")
    assert features.installed_extras(repo, dependencies, python_exe=target) == ["complete", "editable", "partial"]
    with pytest.raises(features.FeatureProbeError, match="feature inventory failed"):
        features.installed_extras(repo, dependencies, python_exe=tmp_path / "missing-python")
