from __future__ import annotations

import importlib.util
import json
import subprocess
import sys
import unittest
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
CHECK = ROOT / "baseline/check_v2_abi_package.py"
BUILD = ROOT / "baseline/build_v2_abi_package.py"


def run(*args: str) -> subprocess.CompletedProcess[str]:
    return subprocess.run([sys.executable, *args], cwd=ROOT, text=True, capture_output=True, check=False)


class V2AbiPackageTests(unittest.TestCase):
    def test_normal_package_is_complete_with_explicit_blocks(self) -> None:
        result = run(str(CHECK))
        self.assertEqual(result.returncode, 0, result.stderr)
        self.assertIn("verified 36 frozen", result.stdout)
        manifest = json.loads((ROOT / "legacy/v2/manifest.json").read_text())
        self.assertEqual(manifest["schemaVersion"], "2.2.0")
        self.assertEqual(len(manifest["records"]), 36)
        self.assertEqual(manifest["blockedDeployedContracts"], [])
        batch = next(record for record in manifest["records"] if record["contract"] == "VaultfireBatchOnboarder")
        self.assertEqual(batch["provenance"]["kind"], "verified-deployed-source")
        self.assertEqual(batch["provenance"]["address"], "0x82c6a0dd34f5cf57f8b98ee118e911b977618890")

    def test_strict_mode_passes_only_with_the_exact_runtime_bound_source_alias(self) -> None:
        result = run(str(CHECK), "--strict")
        self.assertEqual(result.returncode, 0, result.stderr)
        manifest = json.loads((ROOT / "legacy/v2/manifest.json").read_text())
        record = next(item for item in manifest["records"] if item["contract"] == "VaultfireTrustAttestation")
        provenance = record["provenance"]
        self.assertEqual(provenance["sourceContract"], "TrustPortabilityExtension")
        binding = provenance["compilerInput"]["runtimeBytecodeBinding"]
        self.assertEqual(binding["compiledRuntime"]["bytes"], 12259)
        self.assertEqual(
            binding["compiledRuntime"]["sha256"],
            "d76f00942be66a3ed6d0153f397f628ce15103f0c86b14f84117728349f1a81e",
        )
        self.assertEqual(len(binding["deployments"]), 4)

    def test_payload_hash_drift_is_rejected(self) -> None:
        target = ROOT / "legacy/v2/abis/AgentInsurancePool.json"
        original = target.read_bytes()
        try:
            target.write_bytes(original + b" ")
            result = run(str(CHECK))
            self.assertNotEqual(result.returncode, 0)
            self.assertIn("not canonical JSON", result.stderr)
        finally:
            target.write_bytes(original)

    def test_runtime_binding_drift_at_a_deployed_alias_address_is_rejected(self) -> None:
        target = ROOT / "baseline/deployments.json"
        original = target.read_bytes()
        try:
            deployments = json.loads(original)["contracts"]
            deployment = next(
                item
                for item in deployments
                if item["name"] == "VaultfireTrustAttestation" and item["chain"] == "base"
            )
            deployment["onchain"]["bytecodeSha256"] = "00" * 32
            target.write_text(json.dumps({"contracts": deployments}, indent=2) + "\n")
            result = run(str(CHECK), "--strict")
            self.assertNotEqual(result.returncode, 0)
            self.assertIn("deployed runtime binding drift: VaultfireTrustAttestation", result.stderr)
        finally:
            target.write_bytes(original)

    def test_build_requires_pinned_v2_snapshot(self) -> None:
        result = run(str(BUILD), "--v2-root", str(ROOT / "does-not-exist"))
        self.assertNotEqual(result.returncode, 0)
        self.assertIn("cannot resolve pinned V2 HEAD", result.stderr)

    def test_build_refuses_to_substitute_the_default_compiler_for_the_runtime_bound_alias(self) -> None:
        result = run(str(BUILD), "--v2-root", "/home/user/workspace/vaultfire-v3/v2-repo")
        self.assertNotEqual(result.returncode, 0)
        self.assertIn("VaultfireTrustAttestation requires solc 0.8.25+commit.b61c2a91", result.stderr)

    def test_verified_deployed_source_evidence_drift_is_rejected(self) -> None:
        target = ROOT / "baseline/verified-source/blockscout/base/0x82c6a0dd34f5cf57f8b98ee118e911b977618890/getsourcecode.json"
        original = target.read_bytes()
        try:
            target.write_bytes(original + b" ")
            result = run(str(CHECK))
            self.assertNotEqual(result.returncode, 0)
            self.assertIn("verified deployed-source file drift", result.stderr)
        finally:
            target.write_bytes(original)


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