#!/usr/bin/env python3
"""Header, line, anachronism, tense, person, name and length checks: python check_fic.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("’", "'").replace("‘", "'").replace("“", '"').replace("”", '"').strip()
low = a.lower()
fields = {}
for f in ["Fandom", "Rating", "Relationship", "Characters", "Additional Tags", "Summary"]:
    m = re.search(r"^\W*" + f + r"\W*[:\-]\s*(.+)$", a, re.M | re.I)
    fields[f] = m.group(1).strip() if m else None
tags = [t.strip() for t in re.split(r",|;|\|", fields["Additional Tags"] or "") if t.strip()]
summary_words = len(re.findall(r"\S+", fields["Summary"] or ""))
# body = after the last header field line
hdr_end = 0
for f in fields:
    m = re.search(r"^\W*" + f + r"\W*[:\-].*$", a, re.M | re.I)
    if m: hdr_end = max(hdr_end, m.end())
body = a[hdr_end:].strip()
lines = [l for l in body.split("\n") if l.strip()]
title = lines[0].strip("# *_\"") if lines else ""
fic = "\n".join(lines[1:]) if len(lines) > 1 else body
words = len(re.findall(r"\S+", fic))
line_hits = len(re.findall(r"I am not romantic, you know; I never was\.", a))
line_loose = len(re.findall(r"not romantic", low))
ficlow = fic.lower()
nodialog = re.sub(r"\"[^\"]*\"", " ", fic)
first_person = len(re.findall(r"\bI\b|\bmy\b|\bme\b", nodialog))
present = len(re.findall(r"\b(she|elizabeth|charlotte|jane) (is|has|says|walks|looks|sits|takes|turns|thinks|feels|knows|goes|does)\b", nodialog, re.I))
anach = [w for w in ["okay","ok","hi ","hey","guys","teenager","teen","boyfriend","girlfriend","weekend","phone","telephone","photograph","photo","cigarette","sandwich","train ","railway","station","bus","car ","minutes","wristwatch","o'clock","police","email","bike","bicycle","umbrella","stress","stressed","focus","process","relationship","emotional","romantic partner","vibe","perspective","closure","toxic","boundaries","panic attack","anxiety","depressed","self-care"] if re.search(r"\b" + re.escape(w.strip()) + r"\b", ficlow)]
canon = {"elizabeth","lizzy","eliza","charlotte","jane","mary","kitty","catherine","lydia","bennet","lucas","collins","bingley","darcy","wickham","hill","phillips","gardiner","william","maria","longbourn","lucas lodge","meryton","netherfield","hunsford","rosings","kent","hertfordshire","london","de bourgh","lady catherine","forster","denny","fitzwilliam","pemberley","derbyshire","brighton","gracechurch","cheapside","hurst","georgiana","anne","caroline","louisa","jenkinson","charles","george","mr","mrs","miss","sir","lady","god","heaven","lord","england","english","october","november","december","saturday","sunday","monday","tuesday","wednesday","thursday","friday","michaelmas","christmas","the","she","he","it","they","there","then","when","but","and","yet","nor","no","not","if","so","what","how","why","who","that","this","her","his","one","two","three","after","before","perhaps","indeed","well","oh","dear","poor","good","very","how","upon","of","in","at","to","for","with","from","on","by","as","a","an","i","you","we","your","my","our","his","their","its","do","did","does","had","have","has","was","were","be","been","am","is","are","will","would","could","should","may","might","must","shall","can","let","come","go","yes","pray","true","nothing","something","everything","anything","tell","say","said","think","thought","know","knew","believe","believed","hope","hoped","wish","wished","see","saw","look","looked","only","even","still","just","now","here","again","once","soon","never","ever","always","often","quite","too","also","much","more","most","less","least","long","short","great","little","own","same","such","every","each","both","all","any","some","many","few","first","last","next","other","another","new","old","young","dear","kind","cold","warm","late","early","home","house","room","door","window","garden","lane","road","walk","walked","drawing","parlour","hall","stairs","chair","table","fire","letter","note","hand","hands","eyes","face","voice","word","words","morning","afternoon","evening","night","day","week","month","year","years","winter","spring","summer","autumn","sister","sisters","mother","father","brother","brothers","daughter","cousin","friend","friends","family","husband","wife","gentleman","gentlemen","clergyman","parson","rector","patroness","living","parsonage","entail","estate","fortune","income","establishment","comfort","comfortable","home"}
caps = sorted(set(re.findall(r"\b[A-Z][a-z]{2,}\b", fic)))
unknown = [c for c in caps if c.lower() not in canon]
slash = bool(fields["Relationship"] and "/" in fields["Relationship"])
notes = bool(re.search(r"(thanks for reading|author'?s? note|a/n|kudos|comments? (are|welcome)|let me know|hope you enjoy|i hope you)", low))
print(f"header fields: { {k: (v[:60] if v else None) for k, v in fields.items()} }")
print(f"rating general: {bool(fields['Rating'] and 'general' in fields['Rating'].lower())} | relationship exact: {fields['Relationship'] == 'Elizabeth Bennet & Charlotte Lucas'} | slash: {slash} | tags: {len(tags)} | summary words: {summary_words}")
print(f"title: {title[:60]!r}")
print(f"words (below title): {words}  ->  {'in window' if 600 <= words <= 800 else ('SHORT' if words < 600 else 'LONG')}")
print(f"the line exact: {line_hits} time(s) | 'not romantic' anywhere: {line_loose}")
print(f"first-person tokens outside dialogue: {first_person} | present-tense narration hits: {present}")
print(f"anachronisms: {anach}")
print(f"capitalised names not in the canon list (look at these): {unknown}")
print(f"note/thanks after: {notes}")
