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

from __future__ import annotations

import datetime as dt
import json
import sqlite3
import sys

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-125"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")

LENSES = ("morphology", "lexicon", "syntax", "fidelity", "register")

NOTES = (
    "LEXICAL: FIRE AND COOKING (cheatsheet Rule 83 draft; Patz fire-making, "
    "earth-oven, grinding, and meal-sharing examples). 50 rows, avg 4.78 Kuku "
    "words/row. DOMAIN: making fire (baya, jimal, dama-murni-l, jakalamba-l, "
    "kubu, wula, ngunjil, bajar, wumbul), cooking and earth oven (kurrma, "
    "waju-l/wayjul, dinda-l, nyama-l, buyku, yijarri-l, bawa-l, walnga-l), "
    "grinding and bread (nyurrba-l, murni-l, dingka-l, duda-l, damba, kawar, "
    "wunba, wandul, kulbul), and sharing/eating (wambi-ji, nuka-l, dakwuy, "
    "yajin, nganja, jani). QUALITY NOTES: the operator-guide prompt typo "
    "'buri fire' was corrected to baya; jarramali is recorded as thunder, not "
    "a vague storm word; errata's warning against a clean 'wait' verb was "
    "honored by using bunda-l 'sit' + purposive. ALLOMORPHY held: kurrma-nga, "
    "bubu-ngu, baya-nga, ngundu-ba, damba-ka, jukar-bu, mayi-muny, dakwuy-nka. "
    "No denied fire/cooking phantoms re-entered (buri, bibiny, kambar-as-color, "
    "jubaji/nyalbu/kuka, kubarr). Lint GREEN 6347; verified corpus now 6347."
)

LESSONS = [
    (
        "lexicon",
        "Fire/firewood is baya in this production batch. The operator guide's inherited 'buri fire' prompt is unsafe; use baya for the fire/firewood headword, jimal for fire-stick, dama-murni-l for twirling the fire-drill, and jakalamba-l for starting a fire.",
        "cheatsheet Rule 83 + errata Batch-125: baya replaces the prompt typo 'buri'.",
    ),
    (
        "morphology",
        "The cooking/burning verb is Patz waju-l (dict spelling also recorded as wayjul), with surface past wajun. Keep it distinct from dinda-l 'roast', nyama-l 'boil', jani 'well cooked/done', and jirra 'burnt'.",
        "cheatsheet Rule 83: waju-l/wayjul cook-burn, past wajun; cooking-state adjectives constrained to cooking senses.",
    ),
    (
        "syntax",
        "The earth-oven frame is locative-heavy: kurrma-nga 'in the ground oven', bubu-ngu 'in the ground', ngunjil-ba/wumbul-ba 'on/in hot coals', with yijarri-l 'put', bawa-l 'leave', and walnga-l 'take out/open'.",
        "cheatsheet Rule 83: kurrma sequence and locative allomorphs.",
    ),
    (
        "lexicon",
        "Grinding and bread rows should use nyurrba-l 'grind', murni-l 'stir/rub/twist', dingka-l 'knead', duda-l 'pound', damba 'damper', kawar 'honey bread', wunba 'honey', wandul 'fat', and kulbul 'ripe'.",
        "errata Batch-125: food-processing lexemes logged with source-safe senses.",
    ),
    (
        "register",
        "Food-sharing rows should carry the social register without inventing moral vocabulary: use wambi-ji for sharing out all food, daji-l for giving, dakwuy for hungry, yajin for full, and simple parataxis for meal order.",
        "cheatsheet Rule 83: meal-sharing register encoded through attested food/eating verbs.",
    ),
    (
        "process",
        "Two review corrections happened before close: jarramali was reglossed as thunder, and a 'wait near the oven' row was rewritten as bunda-l 'sit' + purposive because the errata warns that 'wait' has no clean single verb.",
        "operator process: targeted lexeme review after lint remains mandatory before close.",
    ),
]

LEXEMES = [
    ("baya", "noun", None, "neutral", "fire; firewood", "batch-125 fire domain: fire/firewood headword; not buri"),
    ("jimal", "noun", None, "neutral", "fire-stick", "batch-125 fire domain: jimal dama-l make fire with fire-stick"),
    ("dama-murnil", "verb-tr", "l", "NA", "twirl a fire-drill", "batch-125 fire domain: dama-murni-ny"),
    ("jakalambal", "verb-tr", "l", "NA", "start a fire", "batch-125 fire domain: jakalamba-ny"),
    ("kubu", "noun", None, "neutral", "smoke", "batch-125 fire domain: kubu smoke"),
    ("wula", "noun", None, "neutral", "flames", "batch-125 fire domain: wula flames"),
    ("ngunjil", "noun", None, "neutral", "charcoal; coals", "batch-125 fire domain: ngunjil wumbul-ba hot coals"),
    ("bajar", "noun", None, "neutral", "ash", "batch-125 fire domain: bajar ash"),
    ("wumbul", "adjective", None, "NA", "hot; warm", "batch-125 fire domain: wumbul hot/warm"),
    ("jirra", "adjective", None, "NA", "burnt", "batch-125 cooking state: kari jirra not burnt"),
    ("jujubala", "noun", None, "neutral", "ironwood", "batch-125 precautionary fire line: jujubala waju"),
    ("jarramali", "noun", None, "neutral", "thunder", "batch-125 precautionary line; do not over-gloss as wind/storm"),
    ("kiway", "noun", None, "neutral", "cold", "batch-125 precautionary line: kiway kada-nyji"),
    ("wajul", "verb-tr/itr", "l", "NA", "cook; burn; light fire", "batch-125: Patz waju-l, dict spelling also wayjul, past wajun"),
    ("dindal", "verb-tr", "l", "NA", "roast", "batch-125: dinda-ny meat/zamia nuts"),
    ("nyamal", "verb-tr", "l", "NA", "boil", "batch-125: nyama-l fish"),
    ("kurrma", "noun", None, "neutral", "ground oven; earth oven", "batch-125: kurrma, kurrma-nga"),
    ("buyku", "noun", None, "neutral", "paperbark", "batch-125: buyku cover on meat in oven"),
    ("yijarril", "verb-tr", "l", "NA", "put; place", "batch-125: minya kurrma-nga yijarri-ny"),
    ("bawal", "verb-tr", "l", "NA", "leave; leave behind", "batch-125: kurrma bawa-ny bubu-ngu"),
    ("walngal", "verb-tr", "l", "NA", "take out; open", "batch-125: minya walnga-ny from oven"),
    ("bakal", "verb-tr", "l", "NA", "dig", "batch-125: kurrma baka-ny; dig oven/open oven"),
    ("dudal", "verb-tr", "l", "NA", "pound; beat", "batch-125: duda-nyjiku after roasting zamia nuts"),
    ("dingkal", "verb-tr", "l", "NA", "knead", "batch-125: damba dingka-ny; Patz damba dingka-nyjiku"),
    ("nyurrbal", "verb-tr", "l", "NA", "grind", "batch-125: nyurrba-ny seeds/yams"),
    ("murnil", "verb-tr", "l", "NA", "stir; rub; twist; grind", "batch-125: kawar murni-ny"),
    ("damba", "noun", None, "neutral", "damper", "batch-125: damba dingka-ny / bunga-ny / waju-ny"),
    ("kawar", "noun", None, "neutral", "honey bread", "batch-125: kawar murni-ny, kawar nganja ngulkurr"),
    ("wunba", "noun", None, "neutral", "honey", "batch-125: wunba honey in meal row"),
    ("wandul", "noun", None, "neutral", "fat", "batch-125: wandul-ji cooked meat"),
    ("kulbul", "adjective", None, "NA", "ripe", "batch-125: wukay kulbul"),
    ("nganja", "noun", None, "neutral", "taste; smell", "batch-125: nganja ngulkurr, good smell/taste"),
    ("dakwuy", "adjective", None, "NA", "hungry", "batch-125: dakwuy hungry; not dakuy"),
    ("yajin", "adjective", None, "NA", "full from eating", "batch-125: yajin-ma-ny after food"),
    ("mujal", "verb-tr", "l", "NA", "collect; gather firewood", "batch-125: baya muja-ny / muja-nka"),
    ("nandal", "verb-tr", "l", "NA", "cover; close", "batch-125: baya nanda-ny jukar-bu"),
    ("buyun-damal", "compound-verb", "l", "NA", "spoil; make bad", "batch-125: mayi kari buyun-dama-ny"),
    ("ngiki", "adjective", None, "NA", "cool; cold", "batch-125: bajar ngiki cool ash"),
    ("duna", "adjective", None, "NA", "wet", "batch-125: juku duna wet wood"),
    ("marral", "adjective", None, "NA", "dry", "batch-125: juku marral dry wood"),
]


def main() -> int:
    db = sqlite3.connect(DB)
    db.execute("PRAGMA foreign_keys = ON")
    db.execute("BEGIN")

    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}")

    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=CASE
                WHEN lexemes.status IN ('phantom-retired', 'watchlist') THEN lexemes.status
                ELSE 'verified'
              END,
              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, "batch-125",
            ),
        )
        db.execute(
            "INSERT INTO lexeme_log(headword, action, detail, created_at) VALUES(?,?,?,?)",
            (headword, "batch-125-verify", note, 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))

    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]
    print(f"closed {LABEL}: 50 accepted rows, {reviews} review passes, verified corpus={verified}")
    return 0


if __name__ == "__main__":
    sys.exit(main())
