#!/usr/bin/env python3
"""Fact, name, structure and length checks on a raw file: python check_world.py raw/<tool>.md"""
import re, sys
text = open(sys.argv[1], encoding="utf-8").read()
ans = text.split("\n## Answer", 1)[1] if "\n## Answer" in text else text
a = ans.replace(" ", " ").replace("–", "-").replace("—", "-").replace("’", "'").strip()
low = a.lower()
heads = ["The Turn", "Three People", "Timeline", "A Tale They Tell", "The Law"]
hpos = {h: [m.start() for m in re.finditer(r"^\W*" + re.escape(h) + r"\W*$", a, re.M | re.I)] for h in heads}
found = [h for h in heads if hpos[h]]
other_heads = [l.strip() for l in a.split("\n") if re.match(r"^\s*(#{1,6}\s|\*\*)", l) and not any(h.lower() in l.lower() for h in heads)]
def section(h, nxt):
    if not hpos[h]: return ""
    s = hpos[h][0]; e = hpos[nxt][0] if nxt and hpos[nxt] else len(a)
    seg = a[s:e].lstrip()
    return seg.split("\n", 1)[1] if "\n" in seg else ""
turn = section("The Turn", "Three People"); people = section("Three People", "Timeline"); tl = section("Timeline", "A Tale They Tell"); tale = section("A Tale They Tell", "The Law"); law = section("The Law", None)
wc = lambda s: len(re.findall(r"\S+", re.sub(r"^\W*(The Turn|Three People|Timeline|A Tale They Tell|The Law)\W*$", "", s, flags=re.M | re.I)))
total = wc(a)
before = a[:hpos["The Turn"][0]].strip() if hpos["The Turn"] else ""
years = [int(y) for y in re.findall(r"\byear\s+(\d{1,3})\b", tl, re.I)]
tl_lines = [l for l in tl.split("\n") if re.search(r"\byear\s+\d", l, re.I)]
banned_names = ["elara","kael","aria","lyra","aeris","seraphina","thorne","zephyr","aetheria","eldoria"]
used_names = [n for n in banned_names if re.search(r"\b" + n + r"\b", low)]
caps = sorted(set(re.findall(r"\b[A-Z][a-z]{2,}(?:\s[A-Z][a-z]{2,})?\b", a)))
endings = [c for c in caps if re.search(r"(iel|ael|yn)$", c.split()[-1])]
known = {"The","Turn","Three","People","Timeline","Tale","They","Tell","Law","Reach","Mudwalkers","Mudwalker","Saltbinders","Saltbinder","Gatewrights","Gatewright","Year","Years"}
unknown = [c for c in caps if c.split()[0] not in known and c not in known and not re.match(r"^(And|But|The|She|He|It|They|We|You|Nobody|Someone|Every|Each|That|This|When|Then|Now|Here|There|Once|Before|After|Below|Above|Inside|Outside|Nothing|Only|Even|Still|Yes|No|Listen|Hush|Come|Sit|Look|Remember|Never|Always|Tonight|Today|Tomorrow|Dawn|Dusk|Night|Morning|Evening|Bronze|Bone|Wood|Salt|Fish|Sea|Mud|Flat|Gate|Wall|Walls|Town|Mainland|One|Two|Four|Five|Six|Seven|Eight|Nine|Ten|First|Last|Some|Most|Many|All|Not|For|From|Into|Onto|Over|Under|With|Without|Because|Until|While|Though|Although|Whatever|Whoever|What|Who|Why|How|Where|Which|Long|Old|Young|Little|Big|Great|High|Low|Good|Bad|Right|Left|Half|Full|Empty|Dry|Wet|Cold|Warm|Dark|Light|Deep|Far|Near|Late|Early|Fast|Slow|Sledge|Sledges|Cart|Rope|Ropes|Net|Nets|Basket|Baskets|Barrel|Barrels|Jar|Jars|Bell|Bells|Drum|Drums|Horn|Horns|Lamp|Lamps|Fire|Smoke|Rain|Wind|Sun|Moon|Stars|Sky|Water|Stone|Stones|Sand|Grass|Weed|Bird|Birds|Gull|Gulls|Crab|Crabs|Eel|Eels|Child|Children|Mother|Father|Grandmother|Grandfather|Aunt|Uncle|Brother|Sister|Son|Daughter|Wife|Husband|Man|Woman|Boy|Girl|Elder|Elders|Guild|Guilds|Master|Masters|Keeper|Keepers|Guide|Guides|Walker|Walkers|Binder|Binders|Wright|Wrights|Founder|Founders|Founding|Council|Watch|Priest|Temple|Church|God|Gods|King|Queen|Lord|Lady)$", c.split()[0])]
fourth = [w for w in ["council","priest","priests","priesthood","temple","church","watch","militia","guard","guards","merchants' league","league","order of","brotherhood","sisterhood","assembly","senate","mayor","magistrate","tithe"] if re.search(r"\b" + re.escape(w) + r"\b", low)]
iron = [m.group(0) for m in re.finditer(r"[^.]*\biron\b[^.]*\.", a)]
animals = [w for w in ["horse","horses","mule","mules","donkey","donkeys","ox","oxen","camel","pony","ponies","cattle","dog-sled","dogsled","rode","riding","rider","saddle","hoof","hooves","cart-horse","stallion","mare"] if re.search(r"\b" + w + r"\b", low)]
earth = [w for w in ["god","gods","goddess","saint","church","priest","chapel","prayer","pray","bible","latin","greek","roman","rome","england","london","coin","coins","penny","shilling","dollar","monday","tuesday","wednesday","thursday","friday","saturday","sunday","january","february","march","april","june","july","august","september","october","november","december","christmas","easter"] if re.search(r"\b" + w + r"\b", low)]
present_turn = len(re.findall(r"\b(is|are|comes|come|rises|open|opens|close|closes|stand|stands|wait|waits|watch|watches)\b", turn.lower()))
past_turn = len(re.findall(r"\b(was|were|came|rose|opened|closed|stood|waited|watched)\b", turn.lower()))
people_names = re.findall(r"\*\*([^*]{2,40})\*\*|^\s*(?:[-*•]|\d+[.)])?\s*([A-Z][a-z]+(?:\s[A-Z][a-z]+)?)\s*[,(:-]", people, re.M)
after = [p for p in re.split(r"\n\s*\n", law.strip()) if p.strip()]
notes = bool(re.search(r"(would you like|let me know|note:|word count|\(\d{3,4} words\)|i've kept|i have kept|i hope)", low))
print(f"headings found ({len(found)}/5): {found} | other headings: {other_heads[:5]}")
print(f"words total: {total}  ->  {'in window' if 700 <= total <= 900 else ('SHORT' if total < 700 else 'LONG')} | The Turn: {wc(turn)} (250-300) | Tale: {wc(tale)} (120-150)")
print(f"text before first heading: {before[:80]!r}")
print(f"timeline: {len(tl_lines)} dated lines, years {years}  ->  {'ok' if len(years)==5 and years==sorted(years) and all(1<=y<=212 for y in years) else 'CHECK'}")
print(f"The Law paragraphs: {len(after)}")
print(f"banned names used: {used_names} | banned endings: {endings}")
print(f"fourth-guild words: {fourth}")
print(f"iron sentences: {iron}")
print(f"animals/riding: {animals}")
print(f"earth words: {earth}")
print(f"The Turn present-tense verbs: {present_turn} | past-tense verbs: {past_turn}")
print(f"capitalised names to look at: {unknown}")
print(f"notes/offer: {notes}")
