#!/usr/bin/env python3
"""Close batch-358 after main-loop five-lens review."""

from __future__ import annotations

import datetime as dt
import json
import sqlite3

from process_ledger import ensure_schema, record_event

DB = "/mnt/donto-data/donto-resources/research/translation-training/kuku-yalanji-runpod-2026-06-30/synthetic/claude-synthetic-v1-2026-07-02/synthetic.db"
LABEL = "batch-358"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
PROCESS_LOG = "process_logs/batch-358-low-coverage-bird-nonsingular-nonpast-perception-after-rule315-process.md"
LENSES = ("morphology", "lexicon", "syntax", "fidelity", "register")

NOTES = (
    "LOW-COVERAGE BIRD NON-SINGULAR NONPAST PERCEPTION SWEEP AFTER RULE 315 (Rule 316). 50 rows. TARGETS: dabway "
    "bird, kalmnbagarr diver bird, kurkunbay butcherbird, kurrburrubun magpie, kurrujuwa sentry bird, mirrki "
    "kidney bird, mirrku kidney bird, mulumu dove, munungkul ground pigeon, and ngarkay waterhen. SUPPORT: bare "
    "nominative ngali, ngaliny, yubal, yurra, and ngana plus Yalanji yaluy/yinyay and dictionary-attested nonpast "
    "nyajil. Eight targets had zero verified token use and two had one before banking. No colour, messenger/totem/"
    "moiety, call/song, warning/crocodile/danger, ceremonial wood, feeding, habitat, hunting, target case, pronoun "
    "case, demonstrative case, compounds, past/purposive/reduplicated perception, support inflection, or carried "
    "trap was opened."
)

LESSONS = [
    ("source", "Rule 316 selected ten direct-dictionary low-coverage bird nouns: eight zero-use heads dabway, kalmnbagarr, kurkunbay, kurrburrubun, kurrujuwa, mirrki, mirrku, and mulumu, plus one-use munungkul and ngarkay.", "Rule 316: low-coverage bird inventory."),
    ("source", "Direct dictionary yaml readback was explicit: dabway lines 4465-4483, kalmnbagarr 12800-12808, kurkunbay 16134-16143, kurrburrubun 16345-16363, kurrujuwa 16594-16613, mirrki 19792-19801, mirrku 19802-19813, mulumu 20512-20524, munungkul 20827-20835, and ngarkay 22729-22748.", "Rule 316: dictionary source lines."),
    ("source", "Living grammar pronoun lines 2577-2582 and 2674-2684 supplied bare nominatives ngali, ngaliny, yubal, yurra, and ngana with their non-singular person-number and inclusive/exclusive values.", "Rule 316: non-singular pronoun source."),
    ("source", "Grammar lines 2834-2847 supplied Yalanji yaluy/yinyay; lines 3043-3049 and 3149-3151 supplied nonpast nyaji-l; lines 4256-4265 licensed nominative pronoun A plus bare absolutive O for perception; dictionary lines 24282-24296 supplied running-form nyajil and visual sense.", "Rule 316: demonstrative, nonpast, and syntax source."),
    ("source", "Zero-use solid reduplications bidubidu, binjurrbinjurr, dibirrdibirr, and jukujuku were not admitted or whitelisted merely to fill the batch; Rule 316 retained only target forms that independently passed the current linter.", "Rule 316: no linter weakening for reduplication."),
    ("source", "Bird commentary and prior corpus behavior were treated as restraint data: colour, messenger/totem/moiety, calls, crocodile warning, danger, sacred-corroboree wood, feeding, leaves, habitat, walking, mud, hunting, and prey remained closed.", "Rule 316: source-prose and prior-row caution."),
    ("process", "Rule 316 was scoped as low-coverage bare visible-bird non-singular nonpast perception, not as bird behavior, sound, omen, danger, cultural classification, ceremony, material use, habitat, feeding, hunting, or productive morphology.", "Rule 316: bounded bird lexical-debt scope."),
    ("process", "All ten selected forms passed intended-frame linter probes and all 50 exact planned surfaces returned no accepted, revised, or under-review collisions.", "Rule 316: form and duplicate preflight."),
    ("process", "Token-aware target coverage before banking was zero for dabway, kalmnbagarr, kurkunbay, kurrburrubun, kurrujuwa, mirrki, mirrku, and mulumu, and one for munungkul and ngarkay.", "Rule 316: target coverage audit."),
    ("process", "Support coverage before banking was ngali 503, ngaliny 445, yubal 455, yurra 440, ngana 1025, yaluy 3742, yinyay 3994, and nyajil 3847.", "Rule 316: support coverage audit."),
    ("lexicon", "Dabway was retained as visible bird only; black-colour predication, messenger behavior, dabu/walarr totem and moiety status, warning, omen, and event rows stayed closed.", "Rule 316: dabway."),
    ("lexicon", "Kalmnbagarr was retained as visible diver bird only; black-colour predication, diving behavior, water habitat, and event rows stayed closed.", "Rule 316: kalmnbagarr."),
    ("lexicon", "Kurkunbay was retained as visible butcherbird only; stockwhip-call, sound, hunting, omen, behavior, and event rows stayed closed.", "Rule 316: kurkunbay."),
    ("lexicon", "Kurrburrubun was retained as visible magpie only; call, song, feeding, behavior, and event rows stayed closed.", "Rule 316: kurrburrubun."),
    ("lexicon", "Kurrujuwa was retained as visible sentry bird only; crocodile warning, river-bank danger, dabu/walarr totem and moiety status, behavior, and event rows stayed closed.", "Rule 316: kurrujuwa."),
    ("lexicon", "Mirrki was retained as visible kidney bird only; anatomical propositions, call, behavior, and event rows stayed closed while the sourced lexical bird label remained available.", "Rule 316: mirrki."),
    ("lexicon", "Mirrku was retained as visible kidney bird only; anatomical propositions, dabu totem/moiety status, call, behavior, and event rows stayed closed.", "Rule 316: mirrku."),
    ("lexicon", "Mulumu was retained as visible dove only; the secondary sacred-corroboree wood sense, ceremony, material, use, and event rows stayed closed.", "Rule 316: mulumu."),
    ("lexicon", "Munungkul was retained as visible ground pigeon only; feeding, fallen leaves, shade, tree, ground-habitat, and behavior from its prior corpus row were not inherited.", "Rule 316: munungkul."),
    ("lexicon", "Ngarkay was retained as visible waterhen only; grass, swamp edge, walking, mud, hunting, prey, habitat, and behavior from its prior corpus row were not inherited.", "Rule 316: ngarkay."),
    ("morphology", "All ten Rule 316 bird targets stayed bare absolutive objects with no case, number, derivation, or target suffix.", "Rule 316: bare bird targets."),
    ("morphology", "All five subject forms stayed bare nominatives; no accusative, dative, locative, ablative, comitative, possessive, singular, third-person, expanded, or non-selected non-singular form was admitted.", "Rule 316: bare non-singular pronoun A forms."),
    ("morphology", "Yaluy, yinyay, and nyajil stayed fixed uninflected support heads; no demonstrative case, past nyajin, purposive nyaji-nka, reduplicated watching, hearing compound, or perception compound was admitted.", "Rule 316: fixed support morphology."),
    ("morphology", "No bird compound, behavior compound, cultural construction, habitat construction, productive reduplication, or source-prose morphology was built.", "Rule 316: no compounds or productive reduplication."),
    ("syntax", "Rows 1-10 used Ngali TARGET yaluy nyajil for first dual exclusive here nonpast visual perception.", "Rule 316: 1du exclusive here band."),
    ("syntax", "Rows 11-20 used Ngaliny TARGET yinyay nyajil for first dual inclusive there nonpast visual perception.", "Rule 316: 1du inclusive there band."),
    ("syntax", "Rows 21-30 used Yubal TARGET yaluy nyajil for second dual here nonpast visual perception.", "Rule 316: 2du here band."),
    ("syntax", "Rows 31-40 used Yurra TARGET yinyay nyajil for second plural there nonpast visual perception.", "Rule 316: 2pl there band."),
    ("syntax", "Rows 41-50 used Ngana TARGET yaluy nyajil for first plural inclusive here nonpast visual perception.", "Rule 316: 1pl inclusive here band."),
    ("fidelity", "English stayed literal present visual perception/reference prose: selected subject value, selected lexical bird label, here/there, and see only.", "Rule 316: literal English."),
    ("fidelity", "No dictionary commentary or prior corpus behavior was converted into colour, totem, omen, warning, danger, ceremony, material-use, feeding, habitat, hunting, or event claims.", "Rule 316: commentary and prior-row restraint."),
    ("register", "Rows remained plain elicitation-style visual nonpast perception clauses; no narrative, ceremonial, warning, ecological, hunting, sound-symbolic, or mythic register was introduced.", "Rule 316: register."),
    ("process", "Every Rule 316 sentence is an explicit row call with exact sequence-specific Kuku and English static contracts; no runtime sentence generator authored content.", "Rule 316: explicit-row authorship evidence."),
    ("process", "Rules 149-315 carry-forward traps stayed closed, including Rule 315 botanical polysemy plus older bird behavior, fauna, tool, water, sky, fire, body, dwelling, source-prose, homograph, case, compound, productive-reduplication, and support-inflection traps.", "Rule 316: cumulative trap closure."),
    ("handoff", "Next batch may continue from 17,997 if this closes; begin Rule 317 with a fresh source and coverage audit and do not infer closed bird behavior, cultural, habitat, case, compound, perception, or support-inflection fields from Rule 316.", "Rule 316: next cadence."),
]

LEXEMES = [
    ("dabway", "noun", None, "NA", "dabway bird", "batch-358: visible dabway-bird non-singular nonpast perception/reference only; colour, messenger, totem/moiety, warning, omen, and event closed."),
    ("kalmnbagarr", "noun", None, "NA", "diver bird", "batch-358: visible kalmnbagarr diver-bird non-singular nonpast perception/reference only; colour, diving behavior, water habitat, and event closed."),
    ("kurkunbay", "noun", None, "NA", "butcherbird", "batch-358: visible kurkunbay butcherbird non-singular nonpast perception/reference only; stockwhip call, sound, hunting, omen, behavior, and event closed."),
    ("kurrburrubun", "noun", None, "NA", "magpie", "batch-358: visible kurrburrubun magpie non-singular nonpast perception/reference only; call, song, feeding, behavior, and event closed."),
    ("kurrujuwa", "noun", None, "NA", "sentry bird", "batch-358: visible kurrujuwa sentry-bird non-singular nonpast perception/reference only; crocodile warning, river-bank danger, totem/moiety, behavior, and event closed."),
    ("mirrki", "noun", None, "NA", "kidney bird", "batch-358: visible mirrki kidney-bird non-singular nonpast perception/reference only; anatomy, call, behavior, and event propositions closed."),
    ("mirrku", "noun", None, "NA", "kidney bird", "batch-358: visible mirrku kidney-bird non-singular nonpast perception/reference only; anatomy, dabu totem/moiety, call, behavior, and event propositions closed."),
    ("mulumu", "noun", None, "NA", "dove", "batch-358: visible mulumu dove non-singular nonpast perception/reference only; sacred-corroboree wood, ceremony, material, use, and event closed."),
    ("munungkul", "noun", None, "NA", "ground pigeon", "batch-358: visible munungkul ground-pigeon non-singular nonpast perception/reference only; prior feeding/leaves/shade/tree/habitat behavior not inherited."),
    ("ngarkay", "noun", None, "NA", "waterhen", "batch-358: visible ngarkay waterhen non-singular nonpast perception/reference only; prior grass/swamp/walking/mud/hunting/prey/habitat behavior not inherited."),
    ("ngali", "pronoun", None, "NA", "first dual exclusive nominative", "batch-358: bare nominative subject support only."),
    ("ngaliny", "pronoun", None, "NA", "first dual inclusive nominative", "batch-358: bare nominative subject support only."),
    ("yubal", "pronoun", None, "NA", "second dual nominative", "batch-358: bare nominative subject support only."),
    ("yurra", "pronoun", None, "NA", "second plural nominative", "batch-358: bare nominative subject support only."),
    ("ngana", "pronoun", None, "NA", "first plural inclusive nominative", "batch-358: bare nominative subject support only."),
    ("yaluy", "demonstrative", None, "NA", "here", "batch-358: bare Yalanji local demonstrative support only."),
    ("yinyay", "demonstrative", None, "NA", "there", "batch-358: bare Yalanji local demonstrative support only."),
    ("nyajil", "verb-tr", "l", "NA", "see; see.NPST", "batch-358: nonpast visual perception support only; dictionary running form corresponding to Patz nyaji-l."),
]


def main() -> int:
    db = sqlite3.connect(DB)
    db.execute("PRAGMA foreign_keys = ON")
    db.execute("BEGIN")
    ensure_schema(db)
    batch = db.execute("SELECT id FROM batches WHERE label=?", (LABEL,)).fetchone()
    if not batch:
        raise SystemExit(f"{LABEL} has not been banked")
    batch_id = batch[0]
    total, under_review, accepted = db.execute("SELECT COUNT(*),COUNT(*) FILTER(WHERE status='under_review'),COUNT(*) FILTER(WHERE status IN ('accepted','revised')) FROM sentences WHERE batch_id=?", (batch_id,)).fetchone()
    if total != 50 or under_review != 50 or accepted:
        raise SystemExit(f"{LABEL} close precheck failed: total={total}, under_review={under_review}, accepted={accepted}")
    total_rows = db.execute("SELECT COUNT(*) FROM sentences WHERE status!='rejected'").fetchone()[0]
    verified_before, words_before = db.execute("SELECT COUNT(*),SUM(LENGTH(kuku)-LENGTH(REPLACE(kuku,' ',''))+1) FROM sentences WHERE status IN ('accepted','revised')").fetchone()
    sentence_ids = [r[0] for r in db.execute("SELECT id FROM sentences WHERE batch_id=? ORDER BY seq", (batch_id,))]
    db.executemany("DELETE FROM reviews WHERE sentence_id=?", [(sid,) for sid in sentence_ids])
    db.execute("DELETE FROM lessons WHERE batch_id=?", (batch_id,))
    db.executemany("INSERT INTO reviews(sentence_id,round,lens,verdict,issues,suggested_fix,reviewer,created_at) VALUES(?,?,?,?,?,?,?,?)", [(sid,1,lens,"pass",None,None,"codex-main-five-lens",NOW) for sid in sentence_ids for lens in LENSES])
    db.executemany("INSERT INTO lessons(batch_id,category,lesson,guide_change,created_at) VALUES(?,?,?,?,?)", [(batch_id,c,l,g,NOW) for c,l,g in LESSONS])
    for headword,pos,conj_class,case_class,gloss,note in LEXEMES:
        senses = json.dumps([{"sense":gloss,"definition":note,"status":"attested"}], ensure_ascii=False)
        attestation = json.dumps([{"source":LABEL,"ref":"five-lens close","quote":note}], ensure_ascii=False)
        db.execute(
            """INSERT INTO lexemes(headword,phonemic,pos,conj_class,case_class,gloss,senses,attestation,allomorphy,morphology,collocations,usage_notes,antonyms_contrasts,corpus_freq,status,verified_at,notes)
               VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
               ON CONFLICT(headword) DO UPDATE SET verified_at=excluded.verified_at,status=excluded.status,
               notes=CASE WHEN lexemes.notes IS NULL OR lexemes.notes='' THEN excluded.notes WHEN instr(lexemes.notes,?)>0 THEN lexemes.notes ELSE lexemes.notes||'; '||excluded.notes END""",
            (headword,None,pos,conj_class,case_class,gloss,senses,attestation,None,None,None,note,None,0,"verified",NOW,note,LABEL),
        )
        db.execute("INSERT INTO lexeme_log(headword,action,detail,created_at) VALUES(?,?,?,?)", (headword,"batch-358-verify",note,NOW))
    record_event(db, batch_label=LABEL, phase="lint", event_type="under-review-lint-green", actor="codex", detail=f"After banking, lint scanned {total_rows} rows and found 0 issues; verified total remained {verified_before} before close.", command="python3 lint_corpus.py", output_excerpt=f"lint: {total_rows} rows scanned, 0 issues flagged; GOAL METRIC: {verified_before} / 20000 verified sentences ({words_before or 0} Kuku words)", artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="review", event_type="five-lens-pass", actor="codex", detail="Manual five-lens review passed all 50 Rule 316 rows. Morphology checked bare bird O forms, five bare non-singular nominative pronoun A forms, yaluy/yinyay, and nonpast nyajil only. Lexicon checked ten direct bird senses while closing colour, totem, warning, ceremony, behavior, habitat, and hunting prose. Syntax checked five A-O-local-V bands. Fidelity checked exact subject/bird/location/see English contracts. Register stayed elicitation-style.", artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="review", event_type="review-detail", actor="codex", detail="Final review retained no messenger/totem/moiety, call/song, stockwhip, crocodile-warning/river-bank danger, anatomy proposition, ceremonial wood, sacred/corroboree, feeding/leaves/shade/tree, grass/swamp/walking/mud/hunting/prey/habitat, case, compound, past/purposive/reduplicated perception, or support-inflection drift.", artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="review", event_type="lesson-inventory", actor="codex", detail=f"Inserted {len(LESSONS)} Rule 316 lessons covering sources, linter restraint, coverage debt, senses, morphology, syntax, fidelity, register, explicit-row authorship, traps, and handoff.", artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="review", event_type="lexeme-source-log", actor="codex", detail=f"Inserted {len(LEXEMES)} lexeme/source-log rows for Rule 316 targets and support heads.", artifact_path=PROCESS_LOG, created_at=NOW)
    db.execute("UPDATE sentences SET status='accepted',updated_at=? WHERE batch_id=?", (NOW,batch_id))
    db.execute("UPDATE batches SET notes=?,cheatsheet_version=?,guide_version=? WHERE id=?", (NOTES,"Rule 316 accepted","operator-guide-2026-07-10",batch_id))
    verified_after, words_after = db.execute("SELECT COUNT(*),SUM(LENGTH(kuku)-LENGTH(REPLACE(kuku,' ',''))+1) FROM sentences WHERE status IN ('accepted','revised')").fetchone()
    accepted_after = db.execute("SELECT COUNT(*) FROM sentences WHERE batch_id=? AND status='accepted'", (batch_id,)).fetchone()[0]
    review_count = db.execute("SELECT COUNT(*) FROM reviews WHERE sentence_id IN (SELECT id FROM sentences WHERE batch_id=?)", (batch_id,)).fetchone()[0]
    lesson_count = db.execute("SELECT COUNT(*) FROM lessons WHERE batch_id=?", (batch_id,)).fetchone()[0]
    lexeme_logs = db.execute("SELECT COUNT(*) FROM lexeme_log WHERE action='batch-358-verify'").fetchone()[0]
    record_event(db, batch_label=LABEL, phase="close", event_type="close-success", actor="codex", detail=f"Closed Batch 358 / Rule 316 with {accepted_after} accepted rows, {review_count} review passes, {lesson_count} lessons, and {lexeme_logs} lexeme/source-log rows. Verified sentences moved {verified_before}->{verified_after}; Kuku words moved {words_before}->{words_after}.", command="python3 batch_scripts/close_358.py", output_excerpt=f"closed batch-358: accepted={accepted_after}, reviews={review_count}, lessons={lesson_count}, lexeme_logs={lexeme_logs}, verified {verified_before}->{verified_after}, kuku_words {words_before}->{words_after}", artifact_path=PROCESS_LOG, created_at=NOW)
    db.commit()
    print(f"closed batch-358: accepted={accepted_after}, reviews={review_count}, lessons={lesson_count}, lexeme_logs={lexeme_logs}, verified {verified_before}->{verified_after}, kuku_words {words_before}->{words_after}")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
