"""The reference analysts are players, not oracles, and the reference exists everywhere."""

from __future__ import annotations

import copy
import inspect

from alert_triage.engine import Engine
from alert_triage.generator import MAX_TURNS, canonical_json, generate, world_for_seed
from alert_triage.policies import POLICIES, SHIPPED, reference_for, run_policy

ALL = range(4096)


def test_every_policy_takes_only_the_view() -> None:
    for name, policy in POLICIES.items():
        params = list(inspect.signature(policy).parameters)
        assert params == ["view"], name


def test_policies_never_mutate_the_world() -> None:
    for seed in range(32):
        world = world_for_seed(seed)
        before = canonical_json(world)
        for policy in POLICIES.values():
            run_policy(policy, world)
        assert canonical_json(world) == before


def test_shipped_policies_are_never_rejected() -> None:
    for seed in range(256):
        world = world_for_seed(seed)
        for name in SHIPPED + ("thorough_wasteful",):
            engine = run_policy(POLICIES[name], world)
            assert engine.rejected == 0, (seed, name)
            assert engine.disposition is not None, (seed, name)


def test_turn_budgets_are_as_documented() -> None:
    for seed in range(128):
        world = world_for_seed(seed)
        assert run_policy(POLICIES["fast"], world).turns <= 2
        assert run_policy(POLICIES["targeted"], world).turns <= 5
        thorough = run_policy(POLICIES["thorough"], world).turns
        assert thorough <= MAX_TURNS - 1
        assert run_policy(POLICIES["thorough_wasteful"], world).turns == thorough + 1


def test_reference_exists_and_the_investigators_catch_everything_on_every_seed() -> None:
    """Lens 0: `reference_minutes` is never null. Lens 1/2: caught 1.0 over 4096, not 24."""
    for seed in ALL:
        world = generate(seed)
        minutes, policy = reference_for(world)
        assert minutes is not None and policy is not None, seed
        for name in ("targeted", "thorough"):
            assert run_policy(POLICIES[name], world).outcome == "solved", (seed, name)


def test_fast_misses_exactly_the_hidden_tier() -> None:
    for seed in range(512):
        world = world_for_seed(seed)
        outcome = run_policy(POLICIES["fast"], world).outcome
        assert (outcome == "solved") == (world["tier"] != "hidden"), seed


def test_reference_is_fast_where_the_screen_suffices() -> None:
    for seed in range(512):
        world = world_for_seed(seed)
        assert world["reference_policy"] == ("targeted" if world["tier"] == "hidden" else "fast"), seed


def test_policies_cannot_see_the_answer() -> None:
    """Run every policy against a view whose world has the hidden fields deleted: identical replies."""
    world = world_for_seed(9)
    stripped = copy.deepcopy(world)
    for key in ("label", "typology", "planted", "overlay", "tier", "template", "reference_minutes", "reference_policy"):
        stripped[key] = None if key != "planted" else []
    for name, policy in POLICIES.items():
        a, b = Engine(world), Engine(stripped)
        while not a.done:
            ra, rb = policy(a.view()), policy(b.view())
            assert ra == rb, name
            a.step(ra)
            b.step(rb)
