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

NOTES = (
    "VISIBLE SKY/CELESTIAL PAST PRONOUN PERCEPTION SWEEP AFTER RULE 274 (Rule 275). 50 rows. TARGETS: "
    "balbay lightning, binyu shooting star, dawar star, jiri sky, kaba rain, kija moon, kurrinkurrin mackerel sky, "
    "kurrubijal morning star, ngurrban cloud, and yiril rainbow. 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 thunder, "
    "wind, weather-entering, cold, storm, lightning-strike event, shooting-star death-spirit/death-omen prose, "
    "moon place/story/creation prose, rainforest/ecology, heaven/sky-mob compounds, fine-day compounds, sun or "
    "sunrise/sunset/midday compounds, target case, target compound, productive reduplication, pronoun case, "
    "demonstrative case, perception compound, support inflection, or recent fire/insect/fish/bird/mammal/reptile/"
    "shellfish/body/landform/dwelling drift was opened."
)

LESSONS = [
    ("source", "Rule 275 selected ten visible sky/celestial target heads: balbay, binyu, dawar, jiri, kaba, kija, kurrinkurrin, kurrubijal, ngurrban, and yiril.", "Rule 275: visible target inventory."),
    ("source", "Direct dictionary line readback was explicit: balbay 903-911, binyu 3066-3074, dawar 5377-5382, jiri 9723-9730, kaba 11674-11680, kija 14146-14155, kurrinkurrin 16409-16417, kurrubijal 16560-16567, ngurrban 23888-23893, and yiril 30422-30427.", "Rule 275: dictionary source lines."),
    ("source", "Patz grammar lines 2577-2586 and 2592-2603 supplied bare nominative ngayu, yundu, nyulu, bula, and ngana.", "Rule 275: pronoun source."),
    ("source", "Patz grammar lines 2682-2686 supported ngana as first plural inclusive and bula as third dual.", "Rule 275: ngana and bula source."),
    ("source", "Patz Table 3.12 lines 2838-2845 supplied Yalanji yaluy 'here' and yinyay 'there'; Rule 275 used only bare local demonstratives.", "Rule 275: demonstrative source."),
    ("source", "Patz lines 2568-2571 supplied nyaji-ny 'see-PAST' and lines 3043-3049 supplied nyaji-l 'see'; Rule 275 used corpus-conventional nyajin as the past perception surface only.", "Rule 275: past perception source."),
    ("process", "Rule 275 excluded thunder, wind, and weather-entering terms because the selected construction is visual past perception, not hearing, feeling, or general weather experience.", "Rule 275: visual-only criterion."),
    ("process", "The first candidate grid found one exact duplicate, Ngana wungar yinyay nyajin. from Batch 195; wungar was excluded instead of special-cased.", "Rule 275: duplicate-led target adjustment."),
    ("process", "Exact duplicate preflight over the final 50 Rule 275 Kuku surfaces returned no accepted, revised, or under-review collisions.", "Rule 275: duplicate preflight."),
    ("process", "Token-aware target coverage before banking after Rule 274 was balbay 16, binyu 1, dawar 57, jiri 74, kaba 197, kija 68, kurrinkurrin 5, kurrubijal 18, ngurrban 57, and yiril 20.", "Rule 275: target coverage audit."),
    ("process", "Support coverage before banking after Rule 274 was ngayu 1351, yundu 1211, nyulu 1826, bula 254, ngana 1000, yaluy 2724, yinyay 2978, and nyajin 1502.", "Rule 275: support coverage audit."),
    ("lexicon", "Balbay remained lightning only; the source example about lightning striking was not converted into a strike-event predicate.", "Rule 275: balbay."),
    ("lexicon", "Binyu remained shooting star only; death-spirit and death-omen belief prose stayed closed.", "Rule 275: binyu."),
    ("lexicon", "Dawar remained star only; no dialect-alternative or star-story claim was imported.", "Rule 275: dawar."),
    ("lexicon", "Jiri remained visible sky only; heaven, fine-day/cloudless-sky compounds, sky-mob, and place compounds stayed closed.", "Rule 275: jiri."),
    ("lexicon", "Kaba remained rain only; rainforest, plant, ecology, and weather-event predicates stayed closed.", "Rule 275: kaba."),
    ("lexicon", "Kija remained moon only; Roaring Meg Falls, moon-story, creation-story, place, and women-creation prose stayed closed.", "Rule 275: kija."),
    ("lexicon", "Kurrinkurrin remained lexicalized mackerel-sky reference; the source spelling mackeral was normalized in English only and did not license productive reduplication.", "Rule 275: kurrinkurrin."),
    ("lexicon", "Kurrubijal remained morning star only, identified by the source as Venus as morning star.", "Rule 275: kurrubijal."),
    ("lexicon", "Ngurrban remained cloud only; no sun-behind-cloud, fog, rain, or weather-event predicate was imported.", "Rule 275: ngurrban."),
    ("lexicon", "Yiril remained rainbow only; rainbow serpent/snake mythology and water-hole landscape extensions stayed closed.", "Rule 275: yiril."),
    ("morphology", "All Rule 275 target nouns stayed bare: no LOC, DAT, ABL, PERL, ERG, INST, COMIT, POSS, PRIV, EXCESS, plural, derivation, or target suffix was admitted.", "Rule 275: 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 275: 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 275: uninflected support."),
    ("morphology", "No target compound, story compound, sky compound, sun compound, or productive reduplication was built from the selected sky/celestial heads.", "Rule 275: no compounds or productive reduplication."),
    ("morphology", "English labels such as shooting star, mackerel sky, and morning star remained target glosses, not Kuku morphology or new event predicates.", "Rule 275: label morphology guard."),
    ("syntax", "Rows 1-10 used Ngayu TARGET yaluy nyajin.", "Rule 275: 1sg here past perception band."),
    ("syntax", "Rows 11-20 used Yundu TARGET yinyay nyajin.", "Rule 275: 2sg there past perception band."),
    ("syntax", "Rows 21-30 used Nyulu TARGET yaluy nyajin.", "Rule 275: 3sg here past perception band."),
    ("syntax", "Rows 31-40 used Bula TARGET yinyay nyajin.", "Rule 275: 3du there past perception band."),
    ("syntax", "Rows 41-50 used Ngana TARGET yinyay nyajin.", "Rule 275: 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 275: literal English."),
    ("fidelity", "The batch did not convert dictionary alternate glosses or source prose into thunder, wind, weather-entering, cold, storm, strike, death, story, creation, place, rainforest, ecology, sun-time, cloudless-sky, or sky-being claims.", "Rule 275: source-prose restraint."),
    ("register", "Rows remained plain elicitation-style visual past perception clauses; no ritual, story, omen, weather report, ecological note, or mythological register was introduced.", "Rule 275: register."),
    ("process", "Rules 149-274 carry-forward traps stayed closed, especially recent fire-reference traps plus older insect/fish/bird/mammal/reptile/shellfish/source-prose traps.", "Rule 275: carry-forward closure."),
    ("handoff", "Next batch may continue from 15,947 if this closes; do not infer thunder, wind, weather-event, death-omen, moon-story, place-name, sun-time, target-case, pronoun-case, perception-compound, or support-inflection grammar from Rule 275.", "Rule 275: next cadence."),
]

LEXEMES = [
    ("balbay", "noun", None, "NA", "lightning", "batch-317: visible lightning perception/reference only; strike-event prose closed."),
    ("binyu", "noun", None, "NA", "shooting star", "batch-317: visible shooting-star perception/reference only; death-spirit and death-omen prose closed."),
    ("dawar", "noun", None, "NA", "star", "batch-317: visible star perception/reference only."),
    ("jiri", "noun", None, "NA", "sky", "batch-317: visible sky perception/reference only; heaven, fine-day/cloudless-sky compounds, sky-mob, and place compounds closed."),
    ("kaba", "noun", None, "NA", "rain", "batch-317: visible rain perception/reference only; rainforest, plant, ecology, and weather-event rows closed."),
    ("kija", "noun", None, "NA", "moon", "batch-317: visible moon perception/reference only; Roaring Meg Falls, moon-story, creation, and place prose closed."),
    ("kurrinkurrin", "noun", None, "NA", "mackerel sky", "batch-317: visible mackerel-sky perception/reference only; lexicalized reduplicated form, not productive reduplication."),
    ("kurrubijal", "noun", None, "NA", "morning star", "batch-317: visible morning-star perception/reference only, Venus as morning star."),
    ("ngurrban", "noun", None, "NA", "cloud", "batch-317: visible cloud perception/reference only; no sun-behind-cloud, fog, rain, or weather event."),
    ("yiril", "noun", None, "NA", "rainbow", "batch-317: visible rainbow perception/reference only; rainbow serpent/snake mythology and water-hole extensions closed."),
    ("ngayu", "pronoun", None, "NA", "first singular nominative", "batch-317: bare nominative subject support only."),
    ("yundu", "pronoun", None, "NA", "second singular nominative", "batch-317: bare nominative subject support only."),
    ("nyulu", "pronoun", None, "NA", "third singular nominative", "batch-317: bare nominative subject support only."),
    ("bula", "pronoun", None, "NA", "third dual nominative", "batch-317: bare nominative subject support only."),
    ("ngana", "pronoun", None, "NA", "first plural inclusive nominative", "batch-317: bare nominative subject support only."),
    ("yaluy", "demonstrative", None, "NA", "here", "batch-317: bare local demonstrative support only."),
    ("yinyay", "demonstrative", None, "NA", "there", "batch-317: bare local demonstrative support only."),
    ("nyajin", "verb", "l", "NA", "saw", "batch-317: 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-317-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 275 rows. Morphology checked bare visible-sky nouns, bare nominative ngayu/yundu/nyulu/bula/ngana, bare yaluy/yinyay, and nyajin past only. Lexicon checked selected visible sky/celestial 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 thunder, wind, weather-entering, cold, storm, lightning-strike event, shooting-star death-spirit/death-omen prose, moon place/story/creation prose, rainforest/ecology, heaven/sky-mob compounds, fine-day/cloudless-sky compounds, sun/sunrise/sunset/midday compounds, target case, productive compound, productive reduplication, pronoun case, demonstrative case, perception compound, support inflection, or recent fire/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 275 lessons covering source checks, visual-only 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 275 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 275 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-317-verify'").fetchone()[0]
    record_event(
        db,
        batch_label=LABEL,
        phase="close",
        event_type="close-success",
        actor="claude-main",
        detail=f"Closed Batch 317 / Rule 275 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_317.py",
        output_excerpt=f"closed batch-317: 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-317: 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())
