from __future__ import annotations

from copy import deepcopy
import os
from pathlib import Path
import unittest

from ap1_m1_junction_128_revalidation import (
    HELDOUT_MOMENTUM_NODES,
    RevalidationError,
    build_128_freeze,
)


ROOT = Path(os.environ["APEIRON_AP1_ROOT"])
PILOT = ROOT / "AP1/APEIRON_AP1_M1_JUNCTION_CONVERGENCE_PILOT_LATEST.json"
TOL96 = ROOT / "AP1/APEIRON_AP1_M1_EXACT_INITIAL_JUNCTION_TOLERANCES_LATEST.json"
RESULT96 = ROOT / "AP1/APEIRON_AP1_M1_EXACT_INITIAL_JUNCTION_HELDOUT_LATEST.json"
CONVERGENCE = ROOT / "AP1/CODE/ap1_m1_junction_convergence.py"
HELDOUT = ROOT / "AP1/CODE/ap1_m1_junction_heldout.py"
CODE = ROOT / "AP1/CODE/ap1_m1_junction_128_revalidation.py"


class AP1M1Junction128RevalidationTests(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.freeze = build_128_freeze(
            PILOT, TOL96, RESULT96, CONVERGENCE, HELDOUT, CODE
        )

    def test_96_is_revoked_only_for_seed_eligibility(self):
        audit = self.freeze["chronology_audit"]
        self.assertTrue(audit["96_can_remain_numerical_pilot"])
        self.assertTrue(audit["96_seed_eligibility_revoked"])
        self.assertFalse(audit["96_seed_was_used_for_background"])

    def test_128_is_unseen_and_frozen(self):
        self.assertEqual(
            self.freeze["thresholds"]["heldout_momentum_nodes"],
            HELDOUT_MOMENTUM_NODES,
        )
        self.assertTrue(self.freeze["tolerances_frozen_before_128_shell_heldout"])
        self.assertFalse(self.freeze["heldout_128_evaluated"])

    def test_strict_caps_are_carried_forward(self):
        self.assertTrue(
            self.freeze["gates"]["strict_caps_carried_forward_unchanged"]
        )
        self.assertEqual(
            self.freeze["thresholds"]["max_abs_raychaudhuri_normalized"],
            4.0e-8,
        )

    def test_mutated_96_result_is_rejected(self):
        import json
        from tempfile import TemporaryDirectory

        value = json.loads(RESULT96.read_text(encoding="utf-8"))
        value["all_exact_initial_junction_gates_pass"] = False
        with TemporaryDirectory() as directory:
            path = Path(directory) / RESULT96.name
            path.write_text(json.dumps(value), encoding="utf-8")
            with self.assertRaises(RevalidationError):
                build_128_freeze(
                    PILOT, TOL96, path, CONVERGENCE, HELDOUT, CODE
                )

    def test_freeze_does_not_release_seed_or_start_background(self):
        self.assertFalse(self.freeze["seed_released"])
        self.assertFalse(self.freeze["new_AP1_M1_background_started"])
        self.assertFalse(self.freeze["physical_response_kernel_started"])


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