"""materialize plan/apply — idempotence + safety + doc-form death (SPEC §6.4, §6.6)."""

from __future__ import annotations

from mgf.secrets import materialize as M
from mgf.secrets import store as S
from tests._store import make_store_env


def _put(env, entry_id: str, value: bytes) -> None:
    S.store_put(
        entry_id,
        value,
        root=env.store_root,
        encrypted_at="2026-07-18T00:00:00Z",
        recipients=[env.founder_pub, env.operator_pub],
    )


def test_plan_is_key_free_and_maps_ids_to_paths(tmp_path) -> None:
    env = make_store_env(tmp_path)
    # No values stored, NO identity given → plan still produces the full id→path map.
    items = M.plan(env.registry, fed_root=env.fed_root, root=env.store_root)
    by_id = {i.id: i for i in items}
    assert set(by_id) == {"test_token", "test_docform", "held_secret"}
    ti = by_id["test_token"]
    assert ti.target == env.fed_root / "mgf" / "my_stuff" / "tokens" / "test_token.txt"
    assert ti.declared_mode == "0600"
    assert ti.store_present is False  # empty store
    assert ti.status == M.STATUS_NO_STORE
    assert by_id["held_secret"].status == M.STATUS_HELD


def test_apply_writes_bare_value_0600_parent_0700(tmp_path) -> None:
    env = make_store_env(tmp_path)
    _put(env, "test_token", b"BARE_VALUE_ok")
    items = M.plan(env.registry, fed_root=env.fed_root, root=env.store_root)
    result = M.apply(
        items, fed_root=env.fed_root, root=env.store_root, identity_path=env.operator_key
    )
    assert result.written == ["test_token"]
    target = env.fed_root / "mgf" / "my_stuff" / "tokens" / "test_token.txt"
    assert target.read_bytes() == b"BARE_VALUE_ok"
    assert oct(target.stat().st_mode & 0o777) == "0o600"
    assert oct((env.fed_root / "mgf" / "my_stuff").stat().st_mode & 0o777) == "0o700"
    assert oct(target.parent.stat().st_mode & 0o777) == "0o700"


def test_apply_is_idempotent(tmp_path) -> None:
    env = make_store_env(tmp_path)
    _put(env, "test_token", b"v1")
    items = M.plan(env.registry, fed_root=env.fed_root, root=env.store_root)
    M.apply(items, fed_root=env.fed_root, root=env.store_root, identity_path=env.operator_key)
    again = M.plan(env.registry, fed_root=env.fed_root, root=env.store_root)
    assert [i for i in again if i.pending] == []  # plan→apply→plan == empty


def test_apply_never_deletes_undeclared_and_reports_leftovers(tmp_path) -> None:
    env = make_store_env(tmp_path)
    _put(env, "test_token", b"v")
    base = env.fed_root / "mgf" / "my_stuff" / "tokens"
    base.mkdir(parents=True)
    undeclared = base / "undeclared.txt"
    undeclared.write_text("keep me", encoding="utf-8")
    leftover = base / "old_token.bak"
    leftover.write_text("junk", encoding="utf-8")
    items = M.plan(env.registry, fed_root=env.fed_root, root=env.store_root)
    result = M.apply(
        items, fed_root=env.fed_root, root=env.store_root, identity_path=env.operator_key
    )
    assert undeclared.exists() and undeclared.read_text(encoding="utf-8") == "keep me"
    assert leftover.exists()  # never auto-deleted
    assert any("old_token.bak" in p for p in result.leftovers)


def test_held_entry_is_refused(tmp_path) -> None:
    env = make_store_env(tmp_path)
    _put(env, "held_secret", b"should-not-materialize")  # even if a value exists
    items = M.plan(env.registry, fed_root=env.fed_root, root=env.store_root)
    result = M.apply(
        items, fed_root=env.fed_root, root=env.store_root, identity_path=env.operator_key
    )
    assert "held_secret" in result.refused_held
    held_target = env.fed_root / "mgf" / "my_stuff" / "tokens" / "held.txt"
    assert not held_target.exists()


def test_chmod_drift_is_pending(tmp_path) -> None:
    env = make_store_env(tmp_path)
    _put(env, "test_token", b"v")
    items = M.plan(env.registry, fed_root=env.fed_root, root=env.store_root)
    M.apply(items, fed_root=env.fed_root, root=env.store_root, identity_path=env.operator_key)
    target = env.fed_root / "mgf" / "my_stuff" / "tokens" / "test_token.txt"
    target.chmod(0o644)
    again = {i.id: i for i in M.plan(env.registry, fed_root=env.fed_root, root=env.store_root)}
    assert again["test_token"].status == M.STATUS_CHMOD
    assert again["test_token"].pending is True


def test_only_restricts_targets(tmp_path) -> None:
    env = make_store_env(tmp_path)
    items = M.plan(env.registry, fed_root=env.fed_root, root=env.store_root, only=["test_token"])
    assert {i.id for i in items} == {"test_token"}


def test_doc_form_elimination(tmp_path) -> None:
    """A multi-line doc-form value → bare single-line materialized file (SPEC §6.6).

    The username / token-name / notes that used to share the file now live in the
    registry entry (purpose/consumers); the materialized file is the bare value only.
    """
    env = make_store_env(tmp_path)
    bare_value = b"ghp_barevaluetoken_only"
    _put(env, "test_docform", bare_value)
    items = M.plan(env.registry, fed_root=env.fed_root, root=env.store_root, only=["test_docform"])
    M.apply(items, fed_root=env.fed_root, root=env.store_root, identity_path=env.operator_key)
    out = env.fed_root / "mgf" / "my_stuff" / "tokens" / "docform.txt"
    content = out.read_bytes()
    assert content == bare_value
    assert content.count(b"\n") == 0  # single bare line, no doc-form prose
    # The metadata is in the registry, not the file.
    entry = env.registry.get("test_docform")
    assert entry is not None and "metadata" not in content.decode()
    assert "doc-form" in entry.purpose
