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

NOTES = (
    "VISIBLE WATER/LANDFORM PAST PRONOUN PERCEPTION SWEEP AFTER RULE 275 (Rule 276). 50 rows. TARGETS: "
    "bana water, dajali deep water, jalun sea, jirka spring, jukar sand, manjal mountain, wawubaja river, yilki "
    "creek, yiri waterfall, and yirri running water. SUPPORT: bare nominative ngayu, yundu, nyulu, bula, and ngana "
    "plus yaluy/yinyay and nyajin. FRAMES: Ngayu TARGET yaluy nyajin, Yundu TARGET yinyay nyajin, Nyulu TARGET "
    "yaluy nyajin, Bula TARGET yinyay nyajin, and Ngana TARGET yinyay nyajin. REVIEW: no drinking, getting, filling, "
    "washing, swimming, crossing, travel, route, road, flood, tide, salt-pan, whale-oil, spring-season, place-name, "
    "mountain story, water-source use, water spirit, fish/shellfish/reptile/plant/ecology, danger, ownership, target "
    "case, target compound, productive reduplication, pronoun case, demonstrative case, perception compound, support "
    "inflection, or recent sky/fire/insect/fish/bird/mammal/reptile/shellfish/body/dwelling drift was opened."
)

LESSONS = [
    ("source", "Rule 276 selected ten visible water/landform target heads: bana, dajali, jalun, jirka, jukar, manjal, wawubaja, yilki, yiri, and yirri.", "Rule 276: visible target inventory."),
    ("source", "Direct dictionary line readback was explicit: bana 1264-1272, dajali 4510-4518, jalun 7612-7620, jirka 9803-9813, jukar 10254-10262, manjal 17832-17840, wawubaja 26813-26821, yilki 30031-30039, yiri 30410-30418, and yirri 30507-30515.", "Rule 276: dictionary source lines."),
    ("source", "Patz grammar lines 2577-2586 and 2592-2603 supplied bare nominative ngayu, yundu, nyulu, bula, and ngana.", "Rule 276: pronoun source."),
    ("source", "Patz grammar lines 2682-2686 supported ngana as first plural inclusive and bula as third dual.", "Rule 276: ngana and bula source."),
    ("source", "Patz Table 3.12 lines 2838-2845 supplied Yalanji yaluy 'here' and yinyay 'there'; Rule 276 used only bare local demonstratives.", "Rule 276: demonstrative source."),
    ("source", "Patz lines 2568-2571 supplied nyaji-ny 'see-PAST' and lines 3043-3049 supplied nyaji-l 'see'; Rule 276 used corpus-conventional nyajin as the past perception surface only.", "Rule 276: past perception source."),
    ("process", "Rule 276 fills visible water/landform reference gaps after Rule 275 without opening water-use, travel, place-name, route, ecology, flood/tide, or event prose.", "Rule 276: water/landform scope."),
    ("process", "Exact duplicate preflight over all 50 planned Rule 276 Kuku surfaces returned no accepted, revised, or under-review collisions.", "Rule 276: duplicate preflight."),
    ("process", "Token-aware target coverage before banking after Rule 275 was bana 608, dajali 48, jalun 93, jirka 8, jukar 88, manjal 35, wawubaja 201, yilki 7, yiri 5, and yirri 5.", "Rule 276: target coverage audit."),
    ("process", "Support coverage before banking after Rule 275 was ngayu 1361, yundu 1221, nyulu 1836, bula 264, ngana 1010, yaluy 2744, yinyay 3008, and nyajin 1552.", "Rule 276: support coverage audit."),
    ("lexicon", "Bana remained water only; drinking, getting, filling, washing, and water-source/use rows stayed closed.", "Rule 276: bana."),
    ("lexicon", "Dajali remained deep water only; no danger, crossing, swimming, or route predicate was imported.", "Rule 276: dajali."),
    ("lexicon", "Jalun remained sea only; flood, seafarer, sea-fauna, salt-water, route, and tide rows stayed closed.", "Rule 276: jalun."),
    ("lexicon", "Jirka remained spring as a water source only; season and place-name readings stayed closed.", "Rule 276: jirka."),
    ("lexicon", "Jukar remained sand only; sandfly, sand goanna, sand whiting, beach-use, and material rows stayed closed.", "Rule 276: jukar."),
    ("lexicon", "Manjal remained mountain only; mountain story, mountain-and-river place, dog legend, route, and place-name prose stayed closed.", "Rule 276: manjal."),
    ("lexicon", "Wawubaja remained river only; travel, route, crossing, bank, place-name, and water-use rows stayed closed.", "Rule 276: wawubaja."),
    ("lexicon", "Yilki remained creek only; creek-place, crossing, travel, ecology, and use prose stayed closed.", "Rule 276: yilki."),
    ("lexicon", "Yiri remained waterfall only; no rainbow yiril, escape yiril, place-name, water-use, or story row was imported.", "Rule 276: yiri."),
    ("lexicon", "Yirri remained running water only; yirri-damal leak, current/flow event, and water-use rows stayed closed.", "Rule 276: yirri."),
    ("morphology", "All Rule 276 target nouns stayed bare: no LOC, DAT, ABL, PERL, ERG, INST, COMIT, POSS, PRIV, EXCESS, plural, derivation, or target suffix was admitted.", "Rule 276: bare targets."),
    ("morphology", "The subject support forms stayed bare nominatives: ngayu, yundu, nyulu, bula, and ngana were not inflected for accusative, dative, locative, ablative, comitative, or possessive.", "Rule 276: bare nominative pronouns."),
    ("morphology", "Yaluy, yinyay, and nyajin stayed uninflected support heads; no demonstrative case, local-derived form, nonpast nyajil, purposive nyaji-nka, reduplicated watching form, or support suffix was admitted.", "Rule 276: uninflected support."),
    ("morphology", "No target compound, place-name compound, water-use construction, route/travel construction, or productive reduplication was built from the water/landform heads.", "Rule 276: no compounds or reduplication."),
    ("morphology", "English labels such as deep water and running water remained target glosses, not Kuku morphology or new event predicates.", "Rule 276: label morphology guard."),
    ("syntax", "Rows 1-10 used Ngayu TARGET yaluy nyajin.", "Rule 276: 1sg here past perception band."),
    ("syntax", "Rows 11-20 used Yundu TARGET yinyay nyajin.", "Rule 276: 2sg there past perception band."),
    ("syntax", "Rows 21-30 used Nyulu TARGET yaluy nyajin.", "Rule 276: 3sg here past perception band."),
    ("syntax", "Rows 31-40 used Bula TARGET yinyay nyajin.", "Rule 276: 3du there past perception band."),
    ("syntax", "Rows 41-50 used Ngana TARGET yinyay nyajin.", "Rule 276: 1pl inclusive there past perception band."),
    ("fidelity", "English stayed literal visual past perception/reference prose: selected subject pronoun value, target label, here/there, and saw only.", "Rule 276: literal English."),
    ("fidelity", "The batch did not convert dictionary alternate glosses or source prose into drinking, getting, filling, washing, swimming, crossing, travel, route, flood, tide, salt-pan, whale-oil, season, place-name, story, ecology, fauna/flora, water-spirit, danger, ownership, or use claims.", "Rule 276: source-prose restraint."),
    ("register", "Rows remained plain elicitation-style visual past perception clauses; no route instruction, travel narrative, ecological note, water-use instruction, danger warning, or story register was introduced.", "Rule 276: register."),
    ("process", "Rules 149-275 carry-forward traps stayed closed, especially recent visible sky/celestial traps plus older water, landform, fire, fauna, body, dwelling, and source-prose traps.", "Rule 276: carry-forward closure."),
    ("handoff", "Next batch may continue from 15,997 if this closes; do not infer water-use, travel, route, place-name, flood/tide, ecology, story, target-case, pronoun-case, perception-compound, or support-inflection grammar from Rule 276.", "Rule 276: next cadence."),
]

LEXEMES = [
    ("bana", "noun", None, "NA", "water", "batch-318: visible water perception/reference only; drinking, getting, filling, washing, and water-use rows closed."),
    ("dajali", "noun", None, "NA", "deep water", "batch-318: visible deep-water perception/reference only; danger, crossing, swimming, and route rows closed."),
    ("jalun", "noun", None, "NA", "sea", "batch-318: visible sea perception/reference only; flood, seafarer, sea-fauna, tide, and route rows closed."),
    ("jirka", "noun", None, "NA", "spring", "batch-318: visible spring/water-source perception/reference only; season and place-name rows closed."),
    ("jukar", "noun", None, "NA", "sand", "batch-318: visible sand perception/reference only; sandfly, sand goanna, sand whiting, beach-use, and material rows closed."),
    ("manjal", "noun", None, "NA", "mountain", "batch-318: visible mountain perception/reference only; mountain story, dog legend, route, and place-name prose closed."),
    ("wawubaja", "noun", None, "NA", "river", "batch-318: visible river perception/reference only; travel, route, crossing, bank, place-name, and water-use rows closed."),
    ("yilki", "noun", None, "NA", "creek", "batch-318: visible creek perception/reference only; creek-place, crossing, travel, ecology, and use prose closed."),
    ("yiri", "noun", None, "NA", "waterfall", "batch-318: visible waterfall perception/reference only; rainbow yiril, escape yiril, place-name, water-use, and story rows closed."),
    ("yirri", "noun", None, "NA", "running water", "batch-318: visible running-water perception/reference only; yirri-damal leak and water-use rows closed."),
    ("ngayu", "pronoun", None, "NA", "first singular nominative", "batch-318: bare nominative subject support only."),
    ("yundu", "pronoun", None, "NA", "second singular nominative", "batch-318: bare nominative subject support only."),
    ("nyulu", "pronoun", None, "NA", "third singular nominative", "batch-318: bare nominative subject support only."),
    ("bula", "pronoun", None, "NA", "third dual nominative", "batch-318: bare nominative subject support only."),
    ("ngana", "pronoun", None, "NA", "first plural inclusive nominative", "batch-318: bare nominative subject support only."),
    ("yaluy", "demonstrative", None, "NA", "here", "batch-318: bare local demonstrative support only."),
    ("yinyay", "demonstrative", None, "NA", "there", "batch-318: bare local demonstrative support only."),
    ("nyajin", "verb", "l", "NA", "saw", "batch-318: 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-318-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 276 rows. Morphology checked bare water/landform nouns, bare nominative ngayu/yundu/nyulu/bula/ngana, bare yaluy/yinyay, and nyajin past only. Lexicon checked selected visible water/landform senses only. Syntax checked five complementary past pronoun-perception frame 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 drinking, getting, filling, washing, swimming, crossing, travel, route, road, flood, tide, salt-pan, whale-oil, spring-season, place-name, mountain story, water-source use, water spirit, fish/shellfish/reptile/plant/ecology, danger, ownership, target case, productive compound, productive reduplication, pronoun case, demonstrative case, perception compound, support inflection, or recent 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 276 lessons covering source checks, water/landform 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 276 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 276 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-318-verify'").fetchone()[0]
    record_event(
        db,
        batch_label=LABEL,
        phase="close",
        event_type="close-success",
        actor="claude-main",
        detail=f"Closed Batch 318 / Rule 276 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_318.py",
        output_excerpt=f"closed batch-318: 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-318: 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())
