#!/usr/bin/env python3
"""Quality Gate: Lock Drift Detection.

Regenerates contracts.lock.json in memory and performs a byte-exact comparison
against the committed version.  Because the lock is deterministic (no
timestamps), identical schemas must produce identical bytes.

Exits 0 if they match, 1 if drift is detected.
"""

from __future__ import annotations

import json
import sys
from pathlib import Path

from abi_control_core.sdk.lock import generate_lock, serialize_lock

REPO_ROOT = Path(__file__).resolve().parent.parent
LOCK_PATH = REPO_ROOT / "contracts.lock.json"


def main() -> int:
    if not LOCK_PATH.exists():
        print("FAIL: contracts.lock.json does not exist")
        print("  Run: abi-core-lock")
        return 1

    committed_text = LOCK_PATH.read_text(encoding="utf-8")
    fresh = generate_lock()
    fresh_text = serialize_lock(fresh)

    if committed_text == fresh_text:
        print(f"PASS: contracts.lock.json is byte-stable ({len(fresh['contracts'])} contracts)")
        return 0

    # Fall back to semantic diff for actionable diagnostics
    committed = json.loads(committed_text)
    committed_contracts = {c["name"]: c["sha256"] for c in committed.get("contracts", [])}
    fresh_contracts = {c["name"]: c["sha256"] for c in fresh["contracts"]}

    drifted: list[str] = []
    for name in sorted(set(committed_contracts) | set(fresh_contracts)):
        old = committed_contracts.get(name)
        new = fresh_contracts.get(name)
        if old != new:
            if old is None:
                drifted.append(f"  + {name} (new, not in lock)")
            elif new is None:
                drifted.append(f"  - {name} (in lock, but schema missing)")
            else:
                drifted.append(f"  ~ {name} (digest changed)")

    if not drifted:
        # Contracts match but bytes differ — likely formatting or stale field
        drifted.append("  (contract digests match but file bytes differ — regenerate)")

    print(f"FAIL: contracts.lock.json has drifted ({len(drifted)} difference(s)):")
    for line in drifted:
        print(line)
    print("\n  Run: abi-core-lock")
    return 1


if __name__ == "__main__":
    sys.exit(main())
