"""ContentDNA Provenance v1 open helper."""
from __future__ import annotations
import base64, hashlib, json, re, unicodedata

PROFILE="contentdividend.canonical-text.v1"

def canonical_text(value: str) -> str:
    value=unicodedata.normalize("NFKC", str(value or ""))
    value=value.replace("\r\n","\n").replace("\r","\n").replace("\x00","")
    lines=[]
    for line in value.split("\n"):
        line=re.sub(r"[ \t\f\v]+"," ",line).strip(" ")
        lines.append(line)
    value="\n".join(lines)
    value=re.sub(r"\n{3,}","\n\n",value)
    return value.strip()

def portable_sha256(value: str) -> str:
    return hashlib.sha256(canonical_text(value).encode("utf-8")).hexdigest()

def _b64u_decode(value: str) -> bytes:
    value=str(value or "").strip()
    value += "=" * (-len(value) % 4)
    return base64.urlsafe_b64decode(value.encode("ascii"))

def _canonical_json(value) -> str:
    return json.dumps(value,sort_keys=True,separators=(",",":"),ensure_ascii=False)

def verify_record_offline(record: dict, public_key_b64u: str) -> dict:
    try:
        from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
    except Exception as exc:
        raise RuntimeError("Offline proof verification requires the optional cryptography package.") from exc
    if not isinstance(record,dict) or not isinstance(record.get("proof"),dict):
        raise ValueError("A signed provenance record is required.")
    proof=record["proof"]
    unsigned={k:v for k,v in record.items() if k!="proof"}
    canonical=_canonical_json(unsigned).encode("utf-8")
    digest=hashlib.sha256(canonical).hexdigest()
    hash_ok=digest==str(proof.get("signed_payload_sha256") or "")
    try:
        key=Ed25519PublicKey.from_public_bytes(_b64u_decode(public_key_b64u))
        key.verify(_b64u_decode(proof.get("signature_b64u") or ""),canonical)
        sig_ok=True
    except Exception:
        sig_ok=False
    return {
        "signature_valid":bool(sig_ok and hash_ok),
        "proof_hash_matches":hash_ok,
        "signed_payload_sha256":digest,
        "provenance_record_grants_rights":False
    }
