#!/usr/bin/env python3
"""
0DATA — verify_proof.py (open-source, ~50 lignes)

Vérificateur INDÉPENDANT d'une preuve scellée 0DATA.
Il recalcule la hash chain et contrôle l'ancrage — sans aucune confiance
en 0DATA. Usage :

    curl -s https://0data.fr/proof.json | python3 verify_proof.py
    # ou
    python3 verify_proof.py proof.json

Protocole 0DATA (public) :
  - chaque mesure m est hachée : h = SHA256( JSON_canonique(m) + prev )
  - JSON_canonique : clés triées (sort_keys), ensure_ascii=False, pas d'espace modifié
  - la chaîne : prev = empreinte du bloc précédent (genèse = 64 zéros)
  - head = empreinte du dernier bloc
  - l'empreinte (head) est ensuite ancrée sur Hedera HCS et/ou Base (registre public)
Vérification publique de l'ancrage : https://hashscan.io/ + topic HCS
"""
import json
import hashlib
import sys


def sha256(s: str) -> str:
    return hashlib.sha256(s.encode()).hexdigest()


def load_proof():
    if len(sys.argv) > 1:
        with open(sys.argv[1], encoding="utf-8") as f:
            return json.load(f)
    return json.load(sys.stdin)


def main():
    proof = load_proof()
    chain = proof.get("chain", [])
    if not chain:
        print("ERREUR : aucune chaîne dans le fichier.")
        sys.exit(1)

    prev = "0" * 64
    all_ok = True
    for i, blk in enumerate(chain, 1):
        # 1) lien de chaîne : prev doit correspondre à l'empreinte du bloc précédent
        if blk.get("prev") != prev:
            print(f"  bloc {i}: ❌ lien de chaîne cassé (prev ≠ empreinte précédente)")
            all_ok = False
        # 2) recalcul de l'empreinte à partir de la pré-image publiée (ou de la mesure)
        pre = blk.get("preimage")
        m = blk.get("measurement")
        if pre is not None:
            payload = pre
        elif m is not None:
            payload = json.dumps(m, sort_keys=True, ensure_ascii=False)
        else:
            print(f"  bloc {i}: ⚠️  pré-image absente, recalcul impossible")
            payload = None
        if payload is not None:
            expected = sha256(payload + prev)
            if expected != blk.get("hash"):
                print(f"  bloc {i}: ❌ empreinte invalide (recalcul ≠ hash)")
                all_ok = False
        prev = blk.get("hash")

    head_ok = (prev == proof.get("head"))
    print(f"\nblocs vérifiés : {len(chain)}")
    print(f"chaîne cohérente : {'✅ OUI' if all_ok else '❌ NON'}")
    print(f"head correspond au dernier bloc : {'✅ OUI' if head_ok else '❌ NON'}")
    print(f"head (empreinte de tête) : {proof.get('head')}")

    h = proof.get("hedera") or {}
    if h.get("topic_id"):
        print(f"\nAncrage Hedera HCS : topic {h['topic_id']} · seq {h.get('sequence_number')}")
        print(f"  Vérifier : https://hashscan.io/{'testnet' if 'testnet' in str(h.get('network','')) else ''}/topic/{h['topic_id']}")
    a = proof.get("anchor") or {}
    if a.get("tx_hash"):
        print(f"\nAncrage Base mainnet : tx {a['tx_hash']}")
        print(f"  Vérifier : https://basescan.org/tx/{a['tx_hash']}")

    sys.exit(0 if (all_ok and head_ok) else 1)


if __name__ == "__main__":
    main()
