#!/usr/bin/env python3
import hashlib
import json
import re
import sys
from pathlib import Path

PROJECT = Path(__file__).resolve().parents[1]
CHAPTERS = PROJECT / "story/chapters"
SPOKEN = PROJECT / "story/spoken-narration.txt"
CANON = PROJECT / "story/story-canon.txt"
REPORT = PROJECT / "story/draft-report.json"
BRIEF = PROJECT / "script/story-brief.json"
OUTLINE = PROJECT / "script/outline.json"
IDENTITY = PROJECT / "script/identity-registry.json"
REVEAL = PROJECT / "script/reveal-ledger.json"
WORD_RE = re.compile(r"[^\W_]+(?:['’-][^\W_]+)*", re.UNICODE)


def sha(path):
    return hashlib.sha256(path.read_bytes()).hexdigest()


def main():
    required = [BRIEF, OUTLINE, IDENTITY, REVEAL, REPORT, SPOKEN, CANON]
    chapters = [CHAPTERS / f"chapter-{index:02d}.txt" for index in range(1, 11)]
    required.extend(chapters)
    missing = [str(path) for path in required if not path.is_file() or path.stat().st_size == 0]
    if missing:
        raise RuntimeError("Story gate missing artifacts: " + ", ".join(missing))
    brief = json.loads(BRIEF.read_text(encoding="utf-8"))
    report = json.loads(REPORT.read_text(encoding="utf-8"))
    joined = "\n\n\n".join(path.read_text(encoding="utf-8").rstrip() for path in chapters) + "\n"
    spoken = SPOKEN.read_text(encoding="utf-8")
    canon = CANON.read_text(encoding="utf-8")
    words = len(WORD_RE.findall(spoken))
    low = int(brief["target_words"]["min"])
    high = int(brief["target_words"]["max"])
    hashes = {
        "spoken": sha(SPOKEN),
        "canon": sha(CANON),
        "outline": sha(OUTLINE),
        "identity": sha(IDENTITY),
        "reveal": sha(REVEAL),
    }
    checks = {
        "exact_join": spoken == joined,
        "canon_byte_identical": canon == spoken,
        "word_range": low <= words <= high,
        "report_verified": report.get("verified") is True,
        "chapter_count": report.get("chapters") == 10,
        "report_word_count": report.get("word_count") == words,
        "report_spoken_hash": report.get("spoken_sha256") == hashes["spoken"],
        "report_canon_hash": report.get("canon_sha256") == hashes["canon"],
        "report_authority_hashes": report.get("outline_sha256") == hashes["outline"] and report.get("identity_sha256") == hashes["identity"] and report.get("reveal_sha256") == hashes["reveal"],
        "qa_checks": all(report.get("checks", {}).get(key) is True for key in ("global_coherence", "comprehension", "dialogue", "originality", "reveal")),
    }
    verified = all(checks.values())
    result = {"verified": verified, "word_count": words, "accepted_range": [low, high], "duration_minutes_at_231_wpm": round(words / 231, 3), "hashes": hashes, "checks": checks}
    print(json.dumps(result, ensure_ascii=False))
    return 0 if verified else 1


if __name__ == "__main__":
    try:
        sys.exit(main())
    except Exception as exc:
        print(f"Story gate blocked: {exc}", file=sys.stderr)
        sys.exit(1)
