#!/usr/bin/env python3
import json
import sys
import time
import urllib.request
from datetime import datetime, timezone

URL = "http://127.0.0.1:9095/contract"
SAMPLES = 10
SLEEP_SEC = 1.0

def parse_iso(ts):
    if not ts:
        return None
    return datetime.fromisoformat(ts.replace("Z", "+00:00"))

def fetch_contract():
    req = urllib.request.Request(URL, headers={"Accept": "application/json"})
    with urllib.request.urlopen(req, timeout=5) as r:
        body = r.read().decode("utf-8")
        return json.loads(body)

def main():
    previous_seq = None
    previous_gal2 = None
    failures = []

    print(f"GAL-2 Time Contract probe")
    print(f"url={URL}")
    print(f"samples={SAMPLES}")
    print("")

    for i in range(1, SAMPLES + 1):
        try:
            data = fetch_contract()
        except Exception as e:
            failures.append(f"sample {i}: fetch_error={e}")
            print(f"sample={i} fetch_error={e}")
            time.sleep(SLEEP_SEC)
            continue

        schema = data.get("schema")
        version = data.get("version")
        mode = data.get("mode")
        safe = data.get("safe_to_consume")
        reason = data.get("reason")
        health = data.get("health")
        seq = data.get("monotonic_sequence")
        gal2_time = data.get("gal2_time")
        utc_time = data.get("utc_time")
        valid_until = data.get("valid_until")
        source_lineage = data.get("source_lineage")

        seq_ok = previous_seq is None or (isinstance(seq, int) and seq > previous_seq)
        gal2_ok = previous_gal2 is None or (gal2_time is not None and gal2_time >= previous_gal2)

        valid_until_ok = True
        if safe is True:
            try:
                valid_dt = parse_iso(valid_until)
                valid_until_ok = valid_dt is not None and valid_dt > datetime.now(timezone.utc)
            except Exception:
                valid_until_ok = False

        schema_ok = schema == "gal2-daemon-time-contract-v1"
        version_ok = version == "1.0.0-contract-rc2"
        lineage_ok = source_lineage == ["gal2_api", "gal2_daemon", "contract_v1"]

        if not schema_ok:
            failures.append(f"sample {i}: bad_schema={schema}")
        if not version_ok:
            failures.append(f"sample {i}: bad_version={version}")
        if not seq_ok:
            failures.append(f"sample {i}: sequence_not_increasing seq={seq} previous={previous_seq}")
        if not gal2_ok:
            failures.append(f"sample {i}: gal2_time_regressed gal2_time={gal2_time} previous={previous_gal2}")
        if not valid_until_ok:
            failures.append(f"sample {i}: invalid_valid_until={valid_until}")
        if not lineage_ok:
            failures.append(f"sample {i}: bad_source_lineage={source_lineage}")

        print(
            f"sample={i} "
            f"mode={mode} safe={safe} health={health} reason={reason} "
            f"seq={seq} seq_ok={seq_ok} "
            f"gal2_time={gal2_time} gal2_ok={gal2_ok} "
            f"utc_time={utc_time} valid_until={valid_until} valid_until_ok={valid_until_ok}"
        )

        previous_seq = seq
        previous_gal2 = gal2_time

        time.sleep(SLEEP_SEC)

    print("")
    if failures:
        print("OVERALL_GAL2_CONTRACT_PROBE=FAIL")
        print("Failures:")
        for f in failures:
            print(f"- {f}")
        sys.exit(1)

    print("OVERALL_GAL2_CONTRACT_PROBE=PASS")
    sys.exit(0)

if __name__ == "__main__":
    main()
