#!/usr/bin/env python3
"""Close batch-314 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-314"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
PROCESS_LOG = "process_logs/batch-314-fire-reference-residual-pronoun-perception-after-rule271-process.md"
LENSES = ("morphology", "lexicon", "syntax", "fidelity", "register")

NOTES = (
    "FIRE-REFERENCE RESIDUAL PRONOUN PERCEPTION SWEEP AFTER RULE 271 (Rule 272). 50 rows. TARGETS: baya fire, "
    "jimal fire stick, jirramar small sticks, kubu smoke, kunjin fire, miyilkura smouldering log, ngalku bush fire, "
    "ngaluri flames, ngunjil charcoal, and wula flames. SUPPORT: bare nominative ngayu, nyulu, ngana, bula, and "
    "jana plus yaluy/yinyay and nyajil. FRAMES: Ngayu TARGET yaluy nyajil, Nyulu TARGET yinyay nyajil, Ngana "
    "TARGET yaluy nyajil, Bula TARGET yinyay nyajil, and Jana TARGET yaluy nyajil. REVIEW: no new fire lexeme, "
    "fire-making, lighting, firewood, collecting, cooking, burning, clearing, spreading, leaping-flame event, "
    "hot-coal/ash extension, smoke-source, smoke-out, loan, ritual-smoke prose, body-fluid homograph, mullet/place/"
    "tadpole homograph, target case, target compound, productive reduplication, pronoun case, demonstrative case, "
    "perception compound, support inflection, or recent insect/fish/bird/mammal/reptile/shellfish/body/landform/"
    "dwelling drift was opened."
)

LESSONS = [
    ("source", "Rule 272 retained the ten checked Rule 236/246/250 fire-reference noun heads: baya, jimal, jirramar, kubu, kunjin, miyilkura, ngalku, ngaluri, ngunjil, and wula.", "Rule 272: retained target inventory."),
    ("source", "Direct dictionary line readback was explicit: baya 1948-1962, jimal 9258-9268, jirramar 9863-9875, kubu 14707-14715, kunjin 15880-15888, miyilkura 19985-19993, ngalku 21918-21926, ngaluri 22014-22025, ngunjil 23679-23688, and wula 27719-27729.", "Rule 272: dictionary source lines."),
    ("source", "Patz grammar lines 2577-2586 supplied bare nominative ngayu, nyulu, and bula plus the third singular variant note.", "Rule 272: pronoun source."),
    ("source", "Patz grammar lines 2581-2582 and 2682-2686 supported ngana as first plural inclusive and jana as modern third plural.", "Rule 272: ngana and jana source."),
    ("source", "Patz Table 3.12 lines 2838-2845 supplied Yalanji yaluy 'here' and yinyay 'there'; Rule 272 used only bare local demonstratives.", "Rule 272: demonstrative source."),
    ("source", "Patz section 3.8.3.2 lines 3043-3049 supplied nyaji-l 'see'; Rule 272 used only nyajil nonpast.", "Rule 272: perception source."),
    ("process", "Rule 272 fills residual zero-collision fire-reference pronoun/deictic bands after Rules 246 and 250, without reopening fire-use semantics.", "Rule 272: residual fire scope."),
    ("process", "Exact duplicate preflight over all 50 planned Rule 272 Kuku surfaces returned no accepted, revised, or under-review collisions.", "Rule 272: duplicate preflight."),
    ("process", "Token-aware target coverage before banking after Rule 271 was baya 464, jimal 48, jirramar 20, kubu 74, kunjin 26, miyilkura 20, ngalku 20, ngaluri 20, ngunjil 83, and wula 64.", "Rule 272: target coverage audit."),
    ("process", "Support coverage before banking after Rule 271 was ngayu 1310, nyulu 1794, ngana 978, bula 222, jana 1512, yaluy 2647, yinyay 2891, and nyajil 3378.", "Rule 272: support coverage audit."),
    ("lexicon", "Baya remained fire only; firewood, baya wayu, lighting, collecting, cooking, and fire-use rows stayed closed.", "Rule 272: baya."),
    ("lexicon", "Jimal remained fire stick only; jimal damal fire-making, twirling, story, and jimalili rows stayed closed.", "Rule 272: jimal."),
    ("lexicon", "Jirramar remained small sticks only; kindling action, starting-fire use, collecting, and material-use rows stayed closed.", "Rule 272: jirramar."),
    ("lexicon", "Kubu remained smoke only; smoke-source, smoke-out, warning, motion, kubu-kubu tadpole, and use rows stayed closed.", "Rule 272: kubu."),
    ("lexicon", "Kunjin remained fire only; no contrast with baya and no kunjirr ritual-smoke/purification prose was imported.", "Rule 272: kunjin."),
    ("lexicon", "Miyilkura remained smouldering log only; burning, cooking, warming, ash, eye/miyil, and use rows stayed closed.", "Rule 272: miyilkura."),
    ("lexicon", "Ngalku remained bush fire only; clearing, spreading, grassfire, danger, warning, and ngalkun mullet rows stayed closed.", "Rule 272: ngalku."),
    ("lexicon", "Ngaluri remained flames only; the source usage with flames leaping up was not converted into a leap-up event predicate.", "Rule 272: ngaluri."),
    ("lexicon", "Ngunjil remained charcoal only; hot coals and hot ashes extensions stayed closed.", "Rule 272: ngunjil."),
    ("lexicon", "Wula remained flames only; dalngarri synonymy and nearby wulay verb drift stayed closed.", "Rule 272: wula."),
    ("morphology", "All Rule 272 target nouns stayed bare: no LOC, DAT, ABL, PERL, ERG, INST, COMIT, POSS, PRIV, EXCESS, plural, derivation, or target suffix was admitted.", "Rule 272: bare targets."),
    ("morphology", "The subject support forms stayed bare nominatives: ngayu, nyulu, ngana, bula, and jana were not inflected for accusative, dative, locative, ablative, comitative, or possessive.", "Rule 272: bare nominative pronouns."),
    ("morphology", "Yaluy, yinyay, and nyajil stayed uninflected support heads; no demonstrative case, local-derived form, verb nominalization, purposive, past, or support suffix was admitted.", "Rule 272: uninflected support."),
    ("morphology", "No target compound, lexicalized trap compound, fire-use construction, smoke-source construction, or productive reduplication was built from the fire-reference heads.", "Rule 272: no compounds or reduplication."),
    ("morphology", "English lexical labels such as fire stick, small sticks, smouldering log, bush fire, flames, and charcoal remained target glosses, not Kuku morphology or new event predicates.", "Rule 272: label morphology guard."),
    ("syntax", "Rows 1-10 used Ngayu TARGET yaluy nyajil.", "Rule 272: 1sg here perception band."),
    ("syntax", "Rows 11-20 used Nyulu TARGET yinyay nyajil.", "Rule 272: 3sg there perception band."),
    ("syntax", "Rows 21-30 used Ngana TARGET yaluy nyajil.", "Rule 272: 1pl inclusive here perception band."),
    ("syntax", "Rows 31-40 used Bula TARGET yinyay nyajil.", "Rule 272: 3du there perception band."),
    ("syntax", "Rows 41-50 used Jana TARGET yaluy nyajil.", "Rule 272: 3pl here perception band."),
    ("fidelity", "English stayed literal perception/reference prose: selected subject pronoun value, target label, here/there, and see only.", "Rule 272: literal English."),
    ("fidelity", "The batch did not convert dictionary alternate glosses or source prose into fire-making, firewood, lighting, collecting, cooking, burning, clearing, spreading, smoke-source, smoke-out, leaping, hot-coal, ash, body-fluid, ritual, story, or use claims.", "Rule 272: source-prose restraint."),
    ("register", "Rows remained plain elicitation-style perception clauses; no danger, warning, ceremony, story, environmental-management, cooking, or instruction register was introduced.", "Rule 272: register."),
    ("process", "Rules 149-271 carry-forward traps stayed closed, especially recent insect/fish/bird/mammal/reptile/shellfish source-prose traps plus older fire action/use/homograph traps.", "Rule 272: carry-forward closure."),
    ("handoff", "Next batch may continue from 15,797 if this closes; do not infer fire-making, firewood, cooking, burning, clearing, spreading, hot-coal/ash, smoke-source, body-fluid homograph, loan, target-case, pronoun-case, perception-compound, or support-inflection grammar from Rule 272.", "Rule 272: next cadence."),
]

LEXEMES = [
    ("baya", "noun", None, "NA", "fire", "batch-314: fire perception/reference only; firewood, baya wayu, lighting, collecting, cooking, and use rows closed."),
    ("jimal", "noun", None, "NA", "fire stick", "batch-314: fire-stick perception/reference only; jimal damal fire-making and jimalili story rows closed."),
    ("jirramar", "noun", None, "NA", "small sticks", "batch-314: small-sticks perception/reference only; starting-fire/kindling-use prose closed."),
    ("kubu", "noun", None, "NA", "smoke", "batch-314: smoke perception/reference only; smoke-source, smoke-out, kubu-kubu tadpole, and warning rows closed."),
    ("kunjin", "noun", None, "NA", "fire", "batch-314: fire perception/reference only; no asserted contrast with baya; kunjirr ritual-smoke prose closed."),
    ("miyilkura", "noun", None, "NA", "smouldering log", "batch-314: smouldering-log perception/reference only; burning, cooking, warming, ash, and eye/miyil drift closed."),
    ("ngalku", "noun", None, "NA", "bush fire", "batch-314: bush-fire perception/reference only; clearing, spreading, danger, warning, and ngalkun mullet closed."),
    ("ngaluri", "noun", None, "NA", "flames", "batch-314: flames perception/reference only; leap-up event predicate closed."),
    ("ngunjil", "noun", None, "NA", "charcoal", "batch-314: charcoal perception/reference only; hot coals and hot ashes extensions closed."),
    ("wula", "noun", None, "NA", "flames", "batch-314: flames perception/reference only; dalngarri synonymy and wulay verb drift closed."),
    ("ngayu", "pronoun", None, "NA", "first singular nominative", "batch-314: bare nominative subject support only."),
    ("nyulu", "pronoun", None, "NA", "third singular nominative", "batch-314: bare nominative subject support only."),
    ("ngana", "pronoun", None, "NA", "first plural inclusive nominative", "batch-314: bare nominative subject support only."),
    ("bula", "pronoun", None, "NA", "third dual nominative", "batch-314: bare nominative subject support only."),
    ("jana", "pronoun", None, "NA", "third plural nominative", "batch-314: bare nominative subject support only."),
    ("yaluy", "demonstrative", None, "NA", "here", "batch-314: bare local demonstrative support only."),
    ("yinyay", "demonstrative", None, "NA", "there", "batch-314: bare local demonstrative support only."),
    ("nyajil", "verb", "l", "NA", "see", "batch-314: nonpast perception support only."),
]


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:
        raise SystemExit(f"{LABEL} must have 50 rows before close; found {total}")
    if accepted:
        raise SystemExit(f"{LABEL} already has {accepted} accepted/revised rows; refusing to overwrite")
    if under_review != 50:
        raise SystemExit(f"{LABEL} must have 50 under_review rows before close; found {under_review}")

    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-314-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 272 rows. Morphology checked bare fire-reference nouns, bare nominative ngayu/nyulu/ngana/bula/jana, bare yaluy/yinyay, and nyajil nonpast only. Lexicon checked selected fire-reference senses only. Syntax checked five residual pronoun-perception frame bands. Fidelity checked literal 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 fire-making, lighting, firewood, collecting, cooking, burning, clearing, spreading, leaping-flame event, smoke-source, smoke-out, hot coals, hot ashes, body-fluid homograph, loan, ritual-smoke prose, mullet/place/tadpole homograph, target case, productive compound, productive reduplication, pronoun case, demonstrative case, perception compound, support inflection, or recent insect/fish/bird/mammal/reptile/shellfish/body/landform/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 272 lessons covering source checks, 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 272 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 272 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-314-verify'"
    ).fetchone()[0]
    record_event(
        db,
        batch_label=LABEL,
        phase="close",
        event_type="close-success",
        actor="claude-main",
        detail=f"Closed Batch 314 / Rule 272 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_314.py",
        output_excerpt=f"closed batch-314: 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 {LABEL}: accepted={accepted_after}, reviews={review_count}, "
        f"lessons={lesson_count}, lexeme_logs={lexeme_logs}, "
        f"verified {verified_before}->{verified_after}, kuku_words {words_before}->{words_after}"
    )
    return 0


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