#!/usr/bin/env python3
"""Close batch-135 after main-loop five-lens 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-135"
NOW = dt.datetime.now(dt.timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
LENSES = ("morphology", "lexicon", "syntax", "fidelity", "register")

NOTES = (
    "LEXICAL: MOVEMENT, PATH-FOLLOWING, RETURN, CARRYING, AND TRAVEL (Patz 5.5.1, text 51, travel text, "
    "and dictionary motion entries). 50 rows. DESIGN: lexical-control batch after Rule 92 NP construction; rows "
    "strengthen route/travel vocabulary without reopening the unresolved `baral` road/path issue. COVERED: "
    "`kada-y` goal/arrival perspective vs `dunga-y` participant/departure perspective; source-shaped text-51 travel "
    "sequence; `jilba-dunga-y` walk/go walkabout; `warri`, `wanarri-y`, and repeated running; `wukurril` follow, "
    "`kangal` chase, `nyunbay` turn back, and motion `-baja`; `wundil`, `jarrakulbal`, and `barrmal` for "
    "bring/take/carry/escort; `walal` enter and `wandil` come out/get up; `dakal`, `jalamal`, `kala-jalamal`, "
    "`daray`, `daray-manil`, `jarmbil`, `mariji-y`; and the minimal pair `mara-warri` crawl vs `marra-warri` fly. "
    "SOURCE CAUTIONS: no productive `baral` rows; no new English-loan vehicle rows; `buwun` boat is source-supported "
    "from Patz despite a dictionary needs-review entry; `jana-nka` is retained because Patz text attests 3pl-DAT; "
    "`kami-nda` follows the dictionary example `kaminda` with explicit segmentation. Pre-close lint scanned 6847 rows "
    "with 0 issues; verified goal metric remained 6797 before close."
)

LESSONS = [
    ("motion", "`kada-y` is not just English 'come': Patz treats it as goal/arrival-perspective motion, including transit toward an implied goal.", "cheatsheet Rule 93: kada/dunga contrast."),
    ("motion", "`dunga-y` is not just English 'go': it can mark participant-perspective motion even when the destination has just been reached.", "cheatsheet Rule 93: kada/dunga contrast."),
    ("motion", "Text 51 gives a compact route template: source ABL, repeated travel, river LOC goal, up/down locational adverbs, follow/chase, and mountain-top arrival.", "operator guide: source-shaped motion batches."),
    ("motion", "`-baja` on motion verbs can mark again/back; keep it separate from degree/intensity uses in non-motion contexts.", "cheatsheet Rule 93: motion -baja."),
    ("lexicon", "`jilba-dunga-y` is the safe walk/go-walkabout construction; short rows may also preserve Patz's `jilba dunga-y` surface.", "cheatsheet Rule 93: walking verbs."),
    ("lexicon", "`wanarri-y` and repeated `warri-ny` rows should remain close to narrative examples; do not turn them into a generic productive progressive template.", "dictionary errata: running/redup caution."),
    ("lexicon", "`wukurril` can mean follow, weave, fence, or imitate; in this batch it is constrained to follow/path-following contexts.", "dictionary errata: wukurril polysemy."),
    ("lexicon", "`barrmal` is escort/take a person somewhere; do not use it for generic object carrying.", "dictionary errata: barrmal person-object frame."),
    ("lexicon", "`wundil` covers bring/take; `jarrakulbal` covers carry; keep the semantic distinction visible in examples.", "cheatsheet Rule 93: carry/bring verbs."),
    ("lexicon", "`wandil` is real and means get up, move out of the way, come out; the older guard against it remains retired.", "dictionary errata: wandil correction retained."),
    ("lexicon", "`mara-warri` crawl and `marra-warri` fly differ by one rhotic; always preserve the spelling contrast.", "dictionary errata: crawl/fly minimal pair."),
    ("lexicon", "`jarmbil-jarmbil` is source-attested for drifting; use it as a lexicalized motion expression rather than a free reduplication model.", "cheatsheet Rule 93: drift caution."),
    ("process", "The unresolved `baral` road/path conflict stays avoided in new synthetic rows; use safer source-shaped route expressions or `jina` only where track/path is intended.", "operator guide: unresolved lexeme conflict handling."),
    ("process", "For high-risk lexical batches, record the source audit before banking, then record lint, close, export, render, and live checks in the process log.", "operator guide: expanded process logging."),
]

LEXEMES = [
    ("kaday", "verb-itr", "y", "NA", "come; move toward a goal; arrive", "batch-135: Patz 5.5.1 goal/arrival-perspective motion."),
    ("dungay", "verb-itr", "y", "NA", "go; participant-perspective motion", "batch-135: Patz 5.5.1 participant/departure-perspective motion."),
    ("kankaday", "verb-itr", "y", "NA", "keep coming; come repeatedly", "batch-135: text-51 and Patz reduplicated coming."),
    ("jilba-dunga-y", "verb-itr", "y", "NA", "walk; go for a walk; go walkabout", "batch-135: walking/go-walkabout construction."),
    ("warri", "verb-itr", "y", "NA", "run; fly", "batch-135: run sense; fly sense kept separate from marra-warri."),
    ("wanarri-y", "verb-itr", "y", "NA", "keep running; run on", "batch-135: narrative running-on form."),
    ("kurrkal-warri", "verb-itr", "y", "NA", "go by a shortcut", "batch-135: shortcut motion compound."),
    ("juru-kulbaway", "verb-itr", "y", "NA", "walk single file", "batch-135: single-file walking compound."),
    ("wukurril", "verb-tr", "l", "NA", "follow", "batch-135: follow/path-following sense."),
    ("kangal", "verb-tr", "l", "NA", "chase", "batch-135: chase frame with animate object."),
    ("nyunbay", "verb-itr", "y", "NA", "return; go back; turn back", "batch-135: Patz travel-text turn-back verb."),
    ("wundil", "verb-tr", "l", "NA", "bring; take", "batch-135: bring/take travel frame."),
    ("jarrakulbal", "verb-tr", "l", "NA", "carry", "batch-135: carry object/person frame."),
    ("barrmal", "verb-tr", "l", "NA", "escort; take a person somewhere", "batch-135: person-escort verb, not generic carrying."),
    ("walal", "verb-itr", "l", "NA", "enter; go into", "batch-135: enter house/place."),
    ("wandil", "verb-itr", "l", "NA", "get up; come out; move out of the way", "batch-135: retained correction that wandil is real."),
    ("dakal", "verb-itr", "l", "NA", "climb", "batch-135: tree-climb frame."),
    ("jalamal", "verb-itr", "l", "NA", "jump; hop; skip; get out of a vehicle/boat", "batch-135: jump source frame; vehicle loans deferred."),
    ("kala-jalamal", "verb-itr", "l", "NA", "jump over", "batch-135: jump-over compound."),
    ("daray", "verb-itr", "y", "NA", "fall", "batch-135: fall from source frame."),
    ("daray-manil", "verb-tr", "l", "NA", "drop; cause to fall", "batch-135: Patz 4.5.2 causative drop."),
    ("jarmbil", "verb-itr", None, "NA", "drift; wash away", "batch-135: source-attested `jarmbil-jarmbil` drifting expression."),
    ("mariji-y", "verb-itr", "y", "NA", "swim through/across water", "batch-135: Patz river-PERL swimming verb."),
    ("mara-warri", "verb-itr", "y", "NA", "crawl", "batch-135: single-r crawl compound."),
    ("marra-warri", "verb-itr", "y", "NA", "fly", "batch-135: double-r fly compound."),
    ("maku-warri", "verb-itr", "y", "NA", "go to meet someone", "batch-135: meet-motion compound."),
    ("maku-wukurril", "verb-tr", "l", "NA", "follow to meet someone", "batch-135: follow-to-meet compound."),
    ("kuwa", "locational", None, "NA", "north-west; west/up-country direction in source travel text", "batch-135: text-51 source/direction term."),
    ("wangkar", "locational", None, "NA", "up; upriver", "batch-135: up/upriver travel direction."),
    ("badabada", "locational", None, "NA", "down there; downward", "batch-135: down/downriver travel direction."),
    ("kudamundu", "locational", None, "NA", "behind; last", "batch-135: behind/following path position."),
    ("ngundu", "locational", None, "NA", "this side; close", "batch-135: close/shallow-water imperative source line."),
    ("wawubaja", "noun", None, "neutral", "river", "batch-135: recurrent route goal and traversal noun."),
    ("buwun", "noun", None, "neutral", "boat; spoon loan in older source material", "batch-135: boat sense source-supported by Patz travel examples; dictionary needs-review retained."),
    ("jina", "noun", None, "neutral", "foot; track/path in tracking context", "batch-135: safer track/path alternative while baral conflict remains open."),
    ("walmba", "noun", None, "neutral", "log", "batch-135: jump-over object."),
    ("jikan", "noun", None, "neutral", "grass", "batch-135: crawl-through ground cover."),
    ("kadanji", "noun", None, "neutral", "black cockatoo", "batch-135: bird subject for flying."),
    ("yalkan", "noun", None, "neutral", "shallow water", "batch-135: Patz text 36 shallow-water goal."),
    ("yilay-yilay", "temporal", None, "NA", "late afternoon", "batch-135: temporal frame for flying row."),
]


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=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-135-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]
    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-135-verify'").fetchone()[0]
    print(
        f"closed {LABEL}: 50 accepted rows, {reviews} review passes, "
        f"{lesson_count} lessons, {lexeme_logs} lexeme/source-log rows, verified corpus={verified}"
    )
    return 0


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