#!/usr/bin/env python3
"""Close batch-333 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-333"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
PROCESS_LOG = "process_logs/batch-333-low-count-traditional-weapon-tool-pronoun-nonpast-perception-after-rule290-process.md"
LENSES = ("morphology", "lexicon", "syntax", "fidelity", "register")

NOTES = (
    "LOW-COUNT VISIBLE TRADITIONAL WEAPON/TOOL TEN-PRONOUN NONPAST PERCEPTION SWEEP AFTER RULE 290 "
    "(Rule 291). 50 rows. TARGETS: kurrajan spear point, nambarr bamboo stick, manbir spear barb, wakay wooden "
    "sword, and wulburr bamboo spear stick. SUPPORT: bare nominative ngayu, yundu, nyulu, ngali, ngaliny, yubal, "
    "bula, nganjin, ngana, and yurra plus yaluy/yinyay and nyajil. REVIEW: Rule 291 explicitly source-checked all "
    "ten pronoun bands and used alternate local demonstratives to avoid prior Rule 289/290 singular-and-third "
    "surfaces. No cooking, earth-oven/vine source, turtle spearing, fire-hardening, nose-piercing, weapon use, "
    "throwing, hunting, fighting, piercing, cutting, material-source, target case, pronoun case, demonstrative case, "
    "target compound, productive reduplication, perception compound, past/purposive/reduplicated perception drift, "
    "support inflection, or carried water/landform/sky/fire/fauna/body/dwelling drift was opened."
)

LESSONS = [
    ("source", "Rule 291 selected five lower-count visible traditional weapon/tool target heads: kurrajan, nambarr, manbir, wakay, and wulburr.", "Rule 291: low-count target inventory."),
    ("source", "Direct dictionary line readback was explicit: kurrajan 16196-16207, nambarr 21516-21526, manbir 17699-17707, wakay 25192-25202, and wulburr 27767-27776.", "Rule 291: dictionary source lines."),
    ("source", "Patz grammar lines 2577-2586 and 2592-2603 supplied the personal pronoun table and base forms for bare nominative ngayu, yundu, nyulu, ngali, ngaliny, yubal, bula, nganjin, ngana, and yurra.", "Rule 291: pronoun source."),
    ("source", "Patz grammar lines 2674-2686 supplied non-singular pronoun contrasts, including ngali exclusive dual, ngana inclusive plural, yubal, yurra, and bula context.", "Rule 291: non-singular source."),
    ("source", "Patz Table 3.12 lines 2838-2845 supplied Yalanji yaluy 'here' and yinyay 'there'; Rule 291 used only bare local demonstratives.", "Rule 291: demonstrative source."),
    ("source", "Patz section 3.8.3.2 lines 3043-3049 supplied nyaji-l 'see', and lines 3149-3151 describe nonpast reference; Rule 291 used corpus-conventional nyajil as the nonpast visual-perception surface.", "Rule 291: nonpast perception source."),
    ("process", "Rule 291 was scoped as pronoun-coverage consolidation over lower-count Rule 289/290 target heads, not as a new lexical or semantic field.", "Rule 291: pronoun coverage scope."),
    ("process", "Exact preflight over all 50 planned surfaces returned no accepted, revised, or under-review collisions.", "Rule 291: duplicate preflight."),
    ("process", "Final preflight retained no durray, jinil, mirru, kurajan, ngurmu, birungubay, or biyul surfaces.", "Rule 291: excluded-head check."),
    ("process", "Token-aware target coverage before banking after Rule 290 was kurrajan 18, nambarr 17, manbir 10, wakay 11, and wulburr 11.", "Rule 291: target coverage audit."),
    ("process", "Support coverage before banking after Rule 290 was ngayu 1231, yundu 827, nyulu 502, ngali 373, ngaliny 315, yubal 325, bula 298, nganjin 228, ngana 895, yurra 330, yaluy 3102, yinyay 3384, and nyajil 3247 by words_used JSON.", "Rule 291: support coverage audit."),
    ("lexicon", "Kurrajan remained visible spear point only; turtle spearing, wattle source, fire-hardening, piercing, and use rows stayed closed.", "Rule 291: kurrajan."),
    ("lexicon", "Nambarr remained visible bamboo stick only; nose-piercing and implement-use rows stayed closed.", "Rule 291: nambarr."),
    ("lexicon", "Manbir remained visible spear barb only; stabbing, hooking, piercing, injury, spear-use, and component-manufacture rows stayed closed.", "Rule 291: manbir."),
    ("lexicon", "Wakay remained visible wooden sword only; people-group source prose, fighting, cutting, and use rows stayed closed.", "Rule 291: wakay."),
    ("lexicon", "Wulburr remained visible bamboo spear stick only; spear use, bamboo-source, hunting, fighting, throwing, and material-source rows stayed closed.", "Rule 291: wulburr."),
    ("morphology", "All Rule 291 target nouns stayed bare absolutive objects: no LOC, DAT, ABL, PERL, ERG, INST, COMIT, POSS, PRIV, EXCESS, plural, derivation, or target suffix was admitted.", "Rule 291: bare targets."),
    ("morphology", "All ten subject support forms stayed bare nominatives: no accusative, dative, locative, ablative, comitative, possessive, or other pronoun case form was admitted.", "Rule 291: bare nominative pronouns."),
    ("morphology", "Yaluy, yinyay, and nyajil stayed uninflected support heads; no demonstrative case, local-derived form, past nyajin, purposive nyaji-nka, reduplicated watching form, or support suffix was admitted.", "Rule 291: uninflected support."),
    ("morphology", "No target compound, object-use construction, material-source construction, place-name compound, pronoun-case construction, or productive reduplication was built from the Rule 291 heads.", "Rule 291: no compounds or reduplication."),
    ("syntax", "Rows 1-5 used Ngayu TARGET yinyay nyajil for first singular there nonpast visual perception.", "Rule 291: 1sg there band."),
    ("syntax", "Rows 6-10 used Yundu TARGET yaluy nyajil for second singular here nonpast visual perception.", "Rule 291: 2sg here band."),
    ("syntax", "Rows 11-15 used Nyulu TARGET yinyay nyajil for third singular there nonpast visual perception.", "Rule 291: 3sg there band."),
    ("syntax", "Rows 16-20 used Ngali TARGET yaluy nyajil for first dual exclusive here nonpast visual perception.", "Rule 291: 1du exclusive here band."),
    ("syntax", "Rows 21-25 used Ngaliny TARGET yinyay nyajil for first dual inclusive there nonpast visual perception.", "Rule 291: 1du inclusive there band."),
    ("syntax", "Rows 26-30 used Yubal TARGET yaluy nyajil for second dual here nonpast visual perception.", "Rule 291: 2du here band."),
    ("syntax", "Rows 31-35 used Bula TARGET yaluy nyajil for third dual here nonpast visual perception.", "Rule 291: 3du here band."),
    ("syntax", "Rows 36-40 used Nganjin TARGET yinyay nyajil for first plural exclusive there nonpast visual perception.", "Rule 291: 1pl exclusive there band."),
    ("syntax", "Rows 41-45 used Ngana TARGET yaluy nyajil for first plural inclusive here nonpast visual perception.", "Rule 291: 1pl inclusive here band."),
    ("syntax", "Rows 46-50 used Yurra TARGET yinyay nyajil for second plural there nonpast visual perception.", "Rule 291: 2pl there band."),
    ("fidelity", "English stayed literal visual nonpast perception/reference prose: selected subject pronoun value, target label, here/there, and see only.", "Rule 291: literal English."),
    ("fidelity", "The batch did not convert dictionary source prose into turtle spearing, fire-hardening, nose-piercing, throwing, hunting, fighting, piercing, cutting, ownership, place, story, or use claims.", "Rule 291: source-prose restraint."),
    ("register", "Rows remained plain elicitation-style visual nonpast perception clauses; no action narrative, object-use instruction, weapon account, manufacturing prose, warning, mythic narrative, or story register was introduced.", "Rule 291: register."),
    ("process", "Rules 149-290 carry-forward traps stayed closed, especially recent weapon/tool perception traps plus older sky, water/landform, fire, fauna, body, dwelling, source-prose, homograph, target-case, pronoun-case, demonstrative-case, perception-compound, target-compound, productive-reduplication, and support-inflection traps.", "Rule 291: carry-forward closure."),
    ("handoff", "Next batch may continue from 16,747 if this closes; do not infer weapon action, cooking, turtle spearing, material source, nose piercing, target case, pronoun case, perception compound, past/purposive/reduplicated perception, productive reduplication, or support-inflection grammar from Rule 291.", "Rule 291: next cadence."),
]

LEXEMES = [
    ("kurrajan", "noun", None, "NA", "spear point", "batch-333: visible spear-point nonpast perception/reference only; turtle-spearing, wattle, fire-hardening, piercing, and use rows closed."),
    ("nambarr", "noun", None, "NA", "bamboo stick", "batch-333: visible bamboo-stick nonpast perception/reference only; nose-piercing and implement-use rows closed."),
    ("manbir", "noun", None, "NA", "spear barb", "batch-333: visible spear-barb nonpast perception/reference only; stabbing, hooking, piercing, injury, spear-use, and manufacture rows closed."),
    ("wakay", "noun", None, "NA", "wooden sword", "batch-333: visible wooden-sword nonpast perception/reference only; people-group source prose, fighting, cutting, and use rows closed."),
    ("wulburr", "noun", None, "NA", "bamboo spear stick", "batch-333: visible bamboo-spear-stick nonpast perception/reference only; spear-use and material-source rows closed."),
    ("ngayu", "pronoun", None, "NA", "first singular nominative", "batch-333: bare nominative subject support only."),
    ("yundu", "pronoun", None, "NA", "second singular nominative", "batch-333: bare nominative subject support only."),
    ("nyulu", "pronoun", None, "NA", "third singular nominative", "batch-333: bare nominative subject support only."),
    ("ngali", "pronoun", None, "NA", "first dual exclusive nominative", "batch-333: bare nominative subject support only."),
    ("ngaliny", "pronoun", None, "NA", "first dual inclusive nominative", "batch-333: bare nominative subject support only."),
    ("yubal", "pronoun", None, "NA", "second dual nominative", "batch-333: bare nominative subject support only."),
    ("bula", "pronoun", None, "NA", "third dual nominative", "batch-333: bare nominative subject support only."),
    ("nganjin", "pronoun", None, "NA", "first plural exclusive nominative", "batch-333: bare nominative subject support only."),
    ("ngana", "pronoun", None, "NA", "first plural inclusive nominative", "batch-333: bare nominative subject support only."),
    ("yurra", "pronoun", None, "NA", "second plural nominative", "batch-333: bare nominative subject support only."),
    ("yaluy", "demonstrative", None, "NA", "here", "batch-333: bare local demonstrative support only."),
    ("yinyay", "demonstrative", None, "NA", "there", "batch-333: bare local demonstrative support only."),
    ("nyajil", "verb", "l", "NA", "see", "batch-333: nonpast visual perception support only, corpus-conventional surface from nyaji-l see-NONPAST."),
]


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 = [row[0] for row 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, "claude-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, category, lesson, guide_change, NOW) for category, lesson, guide_change 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-333-verify", note, NOW),
        )

    record_event(db, batch_label=LABEL, phase="lint", event_type="under-review-lint-green", actor="claude-main", 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="claude-main", detail="Manual five-lens review passed all 50 Rule 291 rows. Morphology checked bare low-count weapon/tool noun objects, ten bare nominative pronoun forms, bare yaluy/yinyay, and nyajil nonpast only. Lexicon checked selected visible target senses only, with kurrajan turtle/fire/piercing, nambarr nose-piercing, manbir injury/use, wakay fighting/cutting, and wulburr spear-use/source extensions closed. Syntax checked ten pronoun-perception bands. Fidelity checked literal visual nonpast reference/perception English. Register stayed plain elicitation-style.", artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="review", event_type="review-detail", actor="claude-main", detail="Final review retained no collided durray/jinil/mirru/kurajan/ngurmu/birungubay heads, Nyungkal biyul, cooking, earth-oven/vine source, turtle spearing, fire-hardening, nose-piercing, weapon use, throwing, hunting, fighting, piercing, cutting, target case, productive compound, productive reduplication, demonstrative case, pronoun case, perception compound, past/purposive/reduplicated perception drift, support inflection, or recent water/landform/sky/fire/fauna/body/dwelling drift.", artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="review", event_type="lesson-inventory", actor="claude-main", detail=f"Inserted {len(LESSONS)} Rule 291 lessons covering source checks, low-count target scope, duplicate avoidance, pronoun coverage, coverage, lexical target senses, morphology, syntax, fidelity, register, process traps, and handoff.", artifact_path=PROCESS_LOG, created_at=NOW)
    record_event(db, batch_label=LABEL, phase="review", event_type="lexeme-source-log", actor="claude-main", detail=f"Inserted {len(LEXEMES)} lexeme/source-log rows for Rule 291 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 291 accepted", "operator-guide-2026-07-09", 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-333-verify'").fetchone()[0]
    record_event(db, batch_label=LABEL, phase="close", event_type="close-success", actor="claude-main", detail=f"Closed Batch 333 / Rule 291 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_333.py", output_excerpt=f"closed batch-333: 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-333: accepted={accepted_after}, reviews={review_count}, lessons={lesson_count}, "
        f"lexeme_logs={lexeme_logs}, verified {verified_before}->{verified_after}, kuku_words {words_before}->{words_after}"
    )
    return 0


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