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

NOTES = (
    "LOW-COUNT VISIBLE TRADITIONAL WEAPON/TOOL TEN-PRONOUN PAST PERCEPTION SWEEP AFTER RULE 291 "
    "(Rule 292). 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 nyajin. REVIEW: Rule 292 explicitly sourced Patz "
    "nyaji-ny/past -ny and used the same zero-collision pronoun/demonstrative pattern as Rule 291. 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, nonpast/purposive/reduplicated perception drift, support inflection, or "
    "carried water/landform/sky/fire/fauna/body/dwelling drift was opened."
)

LESSONS = [
    ("source", "Rule 292 selected the same five lower-count visible traditional weapon/tool target heads as Rule 291: kurrajan, nambarr, manbir, wakay, and wulburr.", "Rule 292: low-count target inventory."),
    ("source", "Direct dictionary line readback stayed explicit: kurrajan 16196-16207, nambarr 21516-21526, manbir 17699-17707, wakay 25192-25202, and wulburr 27767-27776.", "Rule 292: 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 292: 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 292: non-singular source."),
    ("source", "Patz Table 3.12 lines 2838-2845 supplied Yalanji yaluy 'here' and yinyay 'there'; Rule 292 used only bare local demonstratives.", "Rule 292: demonstrative source."),
    ("source", "Patz lines 2568-2571 and 2023 show nyaji-ny 'see-PAST', while lines 3160-3162 state the past -ny function; Rule 292 used corpus-conventional nyajin as the past visual-perception surface.", "Rule 292: past perception source."),
    ("process", "Rule 292 was scoped as the past-tense counterpart to Rule 291's pronoun-coverage consolidation, not as a new lexical or semantic field.", "Rule 292: tense counterpart scope."),
    ("process", "Exact preflight over all 50 planned surfaces returned no accepted, revised, or under-review collisions.", "Rule 292: duplicate preflight."),
    ("process", "Final preflight retained no durray, jinil, mirru, kurajan, ngurmu, birungubay, or biyul surfaces.", "Rule 292: excluded-head check."),
    ("process", "Token-aware target coverage before banking after Rule 291 was kurrajan 28, nambarr 27, manbir 20, wakay 21, and wulburr 21.", "Rule 292: target coverage audit."),
    ("process", "Support coverage before banking after Rule 291 was ngayu 1236, yundu 832, nyulu 507, ngali 378, ngaliny 320, yubal 330, bula 303, nganjin 233, ngana 900, yurra 335, yaluy 3127, yinyay 3409, and nyajin 550 by words_used JSON.", "Rule 292: support coverage audit."),
    ("lexicon", "Kurrajan remained visible spear point only; turtle spearing, wattle source, fire-hardening, piercing, and use rows stayed closed.", "Rule 292: kurrajan."),
    ("lexicon", "Nambarr remained visible bamboo stick only; nose-piercing and implement-use rows stayed closed.", "Rule 292: nambarr."),
    ("lexicon", "Manbir remained visible spear barb only; stabbing, hooking, piercing, injury, spear-use, and component-manufacture rows stayed closed.", "Rule 292: manbir."),
    ("lexicon", "Wakay remained visible wooden sword only; people-group source prose, fighting, cutting, and use rows stayed closed.", "Rule 292: wakay."),
    ("lexicon", "Wulburr remained visible bamboo spear stick only; spear use, bamboo-source, hunting, fighting, throwing, and material-source rows stayed closed.", "Rule 292: wulburr."),
    ("morphology", "All Rule 292 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 292: 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 292: bare nominative pronouns."),
    ("morphology", "Yaluy and yinyay stayed uninflected local demonstratives, and nyajin stayed the only visual-perception verb surface; no nonpast nyajil, purposive nyaji-nka, reduplicated watching form, or support suffix was admitted.", "Rule 292: 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 292 heads.", "Rule 292: no compounds or reduplication."),
    ("syntax", "Rows 1-5 used Ngayu TARGET yinyay nyajin for first singular there past visual perception.", "Rule 292: 1sg there band."),
    ("syntax", "Rows 6-10 used Yundu TARGET yaluy nyajin for second singular here past visual perception.", "Rule 292: 2sg here band."),
    ("syntax", "Rows 11-15 used Nyulu TARGET yinyay nyajin for third singular there past visual perception.", "Rule 292: 3sg there band."),
    ("syntax", "Rows 16-20 used Ngali TARGET yaluy nyajin for first dual exclusive here past visual perception.", "Rule 292: 1du exclusive here band."),
    ("syntax", "Rows 21-25 used Ngaliny TARGET yinyay nyajin for first dual inclusive there past visual perception.", "Rule 292: 1du inclusive there band."),
    ("syntax", "Rows 26-30 used Yubal TARGET yaluy nyajin for second dual here past visual perception.", "Rule 292: 2du here band."),
    ("syntax", "Rows 31-35 used Bula TARGET yaluy nyajin for third dual here past visual perception.", "Rule 292: 3du here band."),
    ("syntax", "Rows 36-40 used Nganjin TARGET yinyay nyajin for first plural exclusive there past visual perception.", "Rule 292: 1pl exclusive there band."),
    ("syntax", "Rows 41-45 used Ngana TARGET yaluy nyajin for first plural inclusive here past visual perception.", "Rule 292: 1pl inclusive here band."),
    ("syntax", "Rows 46-50 used Yurra TARGET yinyay nyajin for second plural there past visual perception.", "Rule 292: 2pl there band."),
    ("fidelity", "English stayed literal visual past perception/reference prose: selected subject pronoun value, target label, here/there, and saw only.", "Rule 292: 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 292: source-prose restraint."),
    ("register", "Rows remained plain elicitation-style visual past perception clauses; no action narrative, object-use instruction, weapon account, manufacturing prose, warning, mythic narrative, or story register was introduced.", "Rule 292: register."),
    ("process", "Rules 149-291 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 292: carry-forward closure."),
    ("handoff", "Next batch may continue from 16,797 if this closes; do not infer weapon action, cooking, turtle spearing, material source, nose piercing, target case, pronoun case, perception compound, nonpast/purposive/reduplicated perception, productive reduplication, or support-inflection grammar from Rule 292.", "Rule 292: next cadence."),
]

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


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-334-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 292 rows. Morphology checked bare low-count weapon/tool noun objects, ten bare nominative pronoun forms, bare yaluy/yinyay, and nyajin past 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-past-perception bands. Fidelity checked literal visual past 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, nonpast/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 292 lessons covering source checks, low-count target scope, duplicate avoidance, tense counterpart scope, 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 292 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 292 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-334-verify'").fetchone()[0]
    record_event(db, batch_label=LABEL, phase="close", event_type="close-success", actor="claude-main", detail=f"Closed Batch 334 / Rule 292 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_334.py", output_excerpt=f"closed batch-334: 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-334: 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())
