import json
from pathlib import Path
import subprocess
import tempfile
import unittest


ROOT = Path(__file__).resolve().parents[1]


class BeeWorkerContractV1Tests(unittest.TestCase):
    def test_health_identity_hashes_the_canonical_bee_manifest_bytes(self) -> None:
        contract = json.loads((ROOT / "tests/fixtures/bee_worker_contract_v1.json").read_text(encoding="utf-8"))
        self.assertEqual("1.0.0", contract["timing_policy_version"])
        source = (ROOT / "classes/RuntimeIdentity.php").read_text(encoding="utf-8")
        self.assertIn("BEE_RUNTIME_MANIFEST", source)
        self.assertIn("bee-runtime-manifest.json", source)
        self.assertIn("hash_file('sha256', $manifest)", source)

    def test_health_counts_only_tests_owned_by_this_worker(self) -> None:
        source = (ROOT / "classes/RuntimeIdentity.php").read_text(encoding="utf-8")
        self.assertIn("bee_worker_id", source)
        self.assertIn("BEE_WORKER_ID", source)
        self.assertNotIn("BEE_WORKER_ID'] ?? 1", source)

    def test_installer_does_not_claim_readiness_before_services_restart(self) -> None:
        source = (ROOT / "deploy/worker/install_worker.sh").read_text(encoding="utf-8")
        self.assertNotIn("printf 'ready", source)
        activation_start = source.index("restart_worker_runtime() {")
        activation_end = source.index("\n}", activation_start)
        activation = source[activation_start:activation_end]
        marker_reset = "rm -f /run/razgar/bee-data-handler.ready /run/razgar/bee-ws.ready"
        self.assertIn(marker_reset, activation)
        self.assertEqual(1, source.count(marker_reset))
        restart_order = (
            "systemctl restart bee_data_handler.service",
            "systemctl restart bee_websocket_server.service",
            "systemctl restart bot_management_api.service",
        )
        for command in restart_order:
            self.assertIn(command, activation)
        self.assertLess(activation.index(restart_order[0]), activation.index(restart_order[1]))
        self.assertLess(activation.index(restart_order[1]), activation.index(restart_order[2]))
        self.assertIn(
            'if [[ "$restart_runtime" == true ]]; then\n  restart_worker_runtime\nfi',
            source,
        )
        data_handler = (ROOT / "beeDataHandler/beeDataHandler.py").read_text(encoding="utf-8")
        self.assertIn("bee-data-handler.ready", data_handler)
        self.assertIn("os.unlink", data_handler)

    def test_manifest_builder_emits_a_deterministic_full_release_manifest(self) -> None:
        builder = ROOT / "deploy/worker/build_runtime_manifest.py"
        with tempfile.TemporaryDirectory() as temporary:
            release = Path(temporary)
            (release / "classes").mkdir()
            (release / "classes/RuntimeIdentity.php").write_text("<?php\n", encoding="utf-8")
            (release / "init.inc.php").write_text("<?php\n", encoding="utf-8")
            subprocess.run(["python", str(builder), str(release)], check=True)
            first = (release / "bee-runtime-manifest.json").read_bytes()
            subprocess.run(["python", str(builder), str(release)], check=True)
            self.assertEqual(first, (release / "bee-runtime-manifest.json").read_bytes())
            manifest = json.loads(first)
            self.assertEqual("bee-runtime-manifest-v1", manifest["manifest_version"])
            self.assertEqual(["classes/RuntimeIdentity.php", "init.inc.php"], list(manifest["files"]))


if __name__ == "__main__":
    unittest.main()
