#!/usr/bin/env python3
from __future__ import annotations

import importlib.util
import json
import tempfile
import unittest
from pathlib import Path

HERE = Path(__file__).resolve().parent
ENROLL_SCRIPT = HERE.parent / "enroll-node.py"
VALIDATOR_SCRIPT = HERE.parent / "validate-enrollment-receipt.py"

def load(name, path):
    spec = importlib.util.spec_from_file_location(name, path)
    assert spec and spec.loader
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

enroll = load("phase2_enroll_for_validator", ENROLL_SCRIPT)
validator = load("phase2_receipt_validator", VALIDATOR_SCRIPT)


class ReceiptValidatorTests(unittest.TestCase):
    def make_receipt(self, root: Path) -> Path:
        receipt = root / "receipt"
        rc = enroll.main([
            "debian4", "--mode", "dry-run", "--repo-root", str(HERE.parents[2]),
            "--fixture", str(HERE / "fixtures/phase2-debian4.json"),
            "--receipt-dir", str(receipt), "--lock-file", str(root / "lock"),
        ])
        self.assertEqual(rc, 0)
        return receipt

    def test_valid_receipt_passes(self):
        with tempfile.TemporaryDirectory() as tmp:
            summary = validator.validate(self.make_receipt(Path(tmp)), expected_candidate="debian4")
            self.assertEqual(summary["status"], "passed")
            self.assertTrue(summary["zero_mutation"])

    def test_mutation_flag_fails(self):
        with tempfile.TemporaryDirectory() as tmp:
            receipt = self.make_receipt(Path(tmp))
            path = receipt / "phase2-result.json"
            value = json.loads(path.read_text())
            value["cluster_mutation_performed"] = True
            path.write_text(json.dumps(value))
            with self.assertRaises(validator.Phase2Error):
                validator.validate(receipt)

    def test_preview_dispatch_enablement_fails(self):
        with tempfile.TemporaryDirectory() as tmp:
            receipt = self.make_receipt(Path(tmp))
            path = receipt / "registry-preview/fleet.json"
            value = json.loads(path.read_text())
            value["nodes"]["debian4"]["execution"] = "normal"
            path.write_text(json.dumps(value))
            with self.assertRaises(validator.Phase2Error):
                validator.validate(receipt)

    def test_plan_digest_tamper_fails(self):
        with tempfile.TemporaryDirectory() as tmp:
            receipt = self.make_receipt(Path(tmp))
            path = receipt / "plan.json"
            value = json.loads(path.read_text())
            value["cluster"]["new_agent_node_ip"] = "100.64.99.99"
            path.write_text(json.dumps(value))
            with self.assertRaises(validator.Phase2Error):
                validator.validate(receipt)


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