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

NOTES = (
    "TREE-REFERENCE LEXICAL EXPANSION AFTER RULE 198 (Rule 199). 50 rows. TARGETS: jinjajalka tree, kurunkal "
    "mangrove, madu sea pine, marngkil ti tree, marrabal ti tree, milbarakal tree, mungari kaori pine, wurmbariji "
    "scrub tree, wuymbariji scrub tree, and kurrun tree. FRAMES: TARGET yaluy, Ngayu TARGET nyajil, Yundu TARGET "
    "yinyay nyajil, Jana TARGET yinyay nyajin, and Ngana TARGET yaluy nyajil. REVIEW: all target heads stayed bare; "
    "tree nouns remained reference heads only; pronoun A stayed bare; yaluy/yinyay stayed local support. No fruit, "
    "seed, food, medicine, poison, sap, timber, bark, wood, oar, woomera, spear, burning, cutting, gathering, "
    "growing/ecology, place-name, story/country, ownership, material-source, target-case, compound, plural, "
    "causative, inchoative, degree, comparison, or tree-use row was opened."
)

LESSONS = [
    ("process", "Rule 199 returned to lexical expansion after Rule 198 and selected ten unused dictionary-backed tree-reference nouns.", "Rule 199: lexical cadence after Rule 198."),
    ("process", "The field was deliberately plain reference, because plant/tree source prose often carries food, medicine, timber, place, or use claims that must not leak into the corpus.", "Rule 199: source prose restraint."),
    ("process", "Exact duplicate preflight over all 50 surfaces returned no cross-corpus accepted/revised/under_review collisions.", "Rule 199: duplicate preflight."),
    ("lexicon", "Jinjajalka was admitted only as an unidentified tree species.", "Rule 199: jinjajalka tree only."),
    ("lexicon", "Kurunkal was admitted only as a mangrove/tree reference; seed prose stayed closed.", "Rule 199: kurunkal reference only."),
    ("lexicon", "Madu was admitted only as sea pine.", "Rule 199: madu sea pine only."),
    ("lexicon", "Marngkil was admitted only as a species of ti tree.", "Rule 199: marngkil ti tree only."),
    ("lexicon", "Marrabal was admitted only as a species of ti tree.", "Rule 199: marrabal ti tree only."),
    ("lexicon", "Milbarakal was admitted only as a tree species with no added use semantics.", "Rule 199: milbarakal tree only."),
    ("lexicon", "Mungari was admitted only as kaori/kauri pine.", "Rule 199: mungari kaori pine only."),
    ("lexicon", "Wurmbariji was admitted only as a scrub-tree reference.", "Rule 199: wurmbariji scrub tree only."),
    ("lexicon", "Wuymbariji was admitted only as a scrub-tree reference.", "Rule 199: wuymbariji scrub tree only."),
    ("lexicon", "Kurrun was admitted only as a tree species with English name unknown.", "Rule 199: kurrun tree only."),
    ("lexicon", "Rejected/closed nearby risks include mirrbangku fruit, miyilabu poison, ngadil timber, nyumbil leech, marril oar wood, wanakan food, wankar necklace/place-colour prose, and yurrunji story/place prose.", "Rule 199: nearby-risk watchlist."),
    ("morphology", "All tree targets stayed bare: no target locative, dative, ablative, perlative, ergative, instrumental, comitative, possessive, privative, degree, comparison, plural, compound, causative, inchoative, or productive reduplication.", "Rule 199: bare target morphology."),
    ("morphology", "Nyaji-l tense stayed consistent: nonpast nyajil and past nyajin with analysis nyaji-l and nyaji-ny.", "Rule 199: perception tense discipline."),
    ("morphology", "Pronoun A heads ngayu, yundu, jana, and ngana stayed bare.", "Rule 199: pronoun A discipline."),
    ("syntax", "Rows 1-10 used TARGET yaluy with no predicator.", "Rule 199: TARGET yaluy."),
    ("syntax", "Rows 11-20 used Ngayu TARGET nyajil.", "Rule 199: 1sg nonpast perception."),
    ("syntax", "Rows 21-30 used Yundu TARGET yinyay nyajil.", "Rule 199: 2sg there perception."),
    ("syntax", "Rows 31-40 used Jana TARGET yinyay nyajin.", "Rule 199: 3pl past there perception."),
    ("syntax", "Rows 41-50 used Ngana TARGET yaluy nyajil.", "Rule 199: 1pl here perception."),
    ("fidelity", "English stayed literal and reference-only: here/there plus see/saw of the selected tree noun.", "Rule 199: literal English."),
    ("fidelity", "No English fruit, seed, edible, food, medicine, poison, sap, timber, wood, bark, oar, woomera, spear, burning, cutting, gathering, growing, ecology, place, story, country, ownership, material, or use wording was imported.", "Rule 199: denied English fields."),
    ("register", "Rows remained plain reference/perception clauses, not botanical, ecological, ethnographic, material-use, or cultural claims.", "Rule 199: reference register."),
    ("handoff", "Next batch may consolidate the Rule 199 tree-reference heads or move to a new bounded lexical field; the tree-use/source-prose traps remain closed.", "Rule 199: next cadence."),
]

LEXEMES = [
    ("jinjajalka", "noun", None, "NA", "jinjajalka tree; unidentified tree species", "batch-241: tree-reference target only; no use prose."),
    ("kurunkal", "noun", None, "NA", "kurunkal mangrove; species of mangrove", "batch-241: mangrove/tree target only; seed prose closed."),
    ("madu", "noun", None, "NA", "madu sea pine", "batch-241: sea pine tree-reference target only."),
    ("marngkil", "noun", None, "NA", "marngkil ti tree; species of ti tree", "batch-241: ti-tree target only; no bark/medicine/use row."),
    ("marrabal", "noun", None, "NA", "marrabal ti tree; species of ti tree", "batch-241: ti-tree target only; no bark/medicine/use row."),
    ("milbarakal", "noun", None, "NA", "milbarakal tree; species of tree", "batch-241: tree-reference target only."),
    ("mungari", "noun", None, "NA", "mungari kaori pine; kauri pine tree", "batch-241: kaori/kauri pine target only."),
    ("wurmbariji", "noun", None, "NA", "wurmbariji scrub tree", "batch-241: scrub-tree target only; no ecology/growing/place row."),
    ("wuymbariji", "noun", None, "NA", "wuymbariji scrub tree", "batch-241: scrub-tree target only; no ecology/growing/place row."),
    ("kurrun", "noun", None, "NA", "kurrun tree; tree species with English name unknown", "batch-241: tree-reference target only."),
    ("yaluy", "demonstrative", None, "NA", "here", "batch-241: local demonstrative support only."),
    ("yinyay", "demonstrative", None, "NA", "there", "batch-241: distal local demonstrative support only."),
    ("nyaji-l", "verb", "l", "NA", "see; hear; perceive", "batch-241: visual perception verb with tree-reference objects."),
    ("ngayu", "pronoun", None, "NA", "I; 1sg nominative", "batch-241: bare pronoun A in nonpast perception rows."),
    ("yundu", "pronoun", None, "NA", "you; 2sg nominative", "batch-241: bare pronoun A in yinyay-supported nonpast perception rows."),
    ("jana", "pronoun", None, "NA", "they; 3pl nominative", "batch-241: bare pronoun A in yinyay-supported past perception rows."),
    ("ngana", "pronoun", None, "NA", "we; 1pl inclusive", "batch-241: bare pronoun A in yaluy-supported nonpast perception rows."),
]


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.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-241-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 by SQL token estimate)",
                 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 199 rows. Morphology checked target heads bare and nyaji-l tense forms. Lexicon checked ten tree-reference senses and kept food, fruit, seed, medicine, poison, sap, timber, bark, wood, oar, woomera, spear, burning, cutting, gathering, growing/ecology, place-name, story/country, ownership, material-source, homograph, and tree-use semantics closed. Syntax checked deictic and pronoun perception frames. Fidelity checked literal reference English. Register stayed plain reference/perception.",
                 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 target case, compound, possessive, comitative, instrumental, locative, dative, ablative, perlative, privative, degree, comparison, plural, causative, inchoative, productive reduplication, fruit, seed, edible, medicine, poison, sap, timber, bark, wood, oar, woomera, spear, burning, cutting, gathering, growing, ecology, place, story, country, ownership, material-source, leech homograph, necklace, or use row.",
                 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 199 lessons covering source checks, target senses, nearby-risk closures, morphology, syntax, fidelity, register, and handoff.",
                 artifact_path="batch_scripts/close_241.py", 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 199 tree targets, local demonstratives, pronouns, and nyaji-l.",
                 artifact_path="batch_scripts/close_241.py", created_at=NOW)
    db.execute("UPDATE batches SET notes=? WHERE id=?", (NOTES, batch_id))
    db.execute("UPDATE sentences SET status='accepted', updated_at=? WHERE batch_id=?", (NOW, batch_id))
    record_event(db, batch_label=LABEL, phase="close", event_type="close-success", actor="claude-main",
                 detail="Closed Batch 241: 50 accepted Rule 199 tree-reference lexical-expansion rows, five-lens reviews, lessons, lexeme/source logs, and process evidence stored.",
                 command="python3 batch_scripts/close_241.py", artifact_path="batch_scripts/close_241.py", created_at=NOW)
    db.commit()

    reviews = db.execute("SELECT COUNT(*) FROM reviews WHERE sentence_id IN (SELECT id FROM sentences WHERE batch_id=?)", (batch_id,)).fetchone()[0]
    verified = db.execute("SELECT COUNT(*) FROM sentences WHERE status IN ('accepted','revised')").fetchone()[0]
    under_review_remaining = db.execute("SELECT COUNT(*) FROM sentences WHERE status='under_review'").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 LIKE 'batch-241%'").fetchone()[0]
    process_events = db.execute("SELECT COUNT(*) FROM process_events WHERE batch_label=?", (LABEL,)).fetchone()[0]
    print(f"closed {LABEL}: 50 accepted rows, {reviews} review passes, {lesson_count} lessons, {lexeme_logs} lexeme/source-log rows, {process_events} process events, under_review={under_review_remaining}, verified corpus={verified}")
    return 0


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