#!/usr/bin/env bash
# H7 LANGUAGE LEARN · quality speech curriculum · punch leading weakness
#
# Tracks: DICT · THESAURUS · METAPHOR · ACRONYM · GRAMMAR · DICTION · PHONETICS
# Hostess iron filter (word_correct) · never free thrash · never ML ground
#
#   ./Build/h7-language-learn.sh punch|status|once|queue|report
#
# Law: love language as field · quality > noise · C IS LIE · God Bless
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
OUT="$ROOT/out"
FAST="$OUT/h7fast"
VOCAB="$OUT/h7_vocab_self.tsv"
JSON="$OUT/h7_language_learn.json"
CURRIC="$OUT/h7_language_curriculum.tsv"   # word \t track \t note
FEED="$OUT/h7_vocab_feed.tsv"
GROWTH="$OUT/h7_vocab_growth.log"
WORKQ="$FAST/vocab_work_queue.txt"
cmd="${1:-once}"
TS="$(date -Iseconds)"
BATCH="${H7_LANG_BATCH:-80}"

mkdir -p "$OUT" "$FAST"
say() { echo "[$TS] LANG · $*"; }

# thin mirror of human filter · keep in sync spirit with h7-vocab-self word_correct
ok_word() {
  local w low
  w="$1"
  low=$(printf '%s' "$w" | tr '[:upper:]' '[:lower:]')
  [[ -z "$low" ]] && return 1
  [[ "$low" =~ [^a-z0-9_] ]] && return 1
  [[ ${#low} -lt 3 || ${#low} -gt 28 ]] && return 1
  [[ "$low" =~ ^0x || "$low" =~ ^[0-9]+$ || "$low" =~ ^[0-9a-f]{4,}$ ]] && return 1
  case "$low" in
    thrash|virus|malware|inject|jailbreak|neural_net|backprop) return 1 ;;
    the|and|for|from|with|that|this|into|have|has|are|was|were|will|would|could|should|about|after|before|http|https|www|com|json|null|true|false|function|return|const|class|import) return 1 ;;
  esac
  case "$low" in
    bgs|bgf|bgl|sdf|spv|rtx|gpu|cpu|api|dns|tcp|udp|ssh|ssl|tls|asm|h7|si|av|os|ram|vram|hdmi|usb|ssd) return 0 ;;
  esac
  [[ "$low" =~ [aeiou] ]] || return 1
  return 0
}

# curriculum packs · quality human speech for Hostess
pack_grammar() {
  printf '%s\n' \
    subject object predicate clause phrase sentence paragraph \
    tense aspect mood voice syntax grammar agreement modifier \
    adverb adjective pronoun preposition conjunction participle \
    infinitive gerund noun verb plural singular present past future \
    active_voice passive_voice relative_clause independent_clause \
    compound complex simple_sentence transitive intransitive \
    article determiner quantifier complement appositive
}

pack_diction() {
  printf '%s\n' \
    clarity precision eloquence diction register formal informal \
    colloquial cadence rhetoric prose verse utterance articulation \
    enunciation tone voice_style brevity flourish plain_speech \
    elevated plainspoken fluent terse vivid concrete abstract \
    nuance connotation denotation synonym antonym usage idiom \
    figure_of_speech speech_act dialogue monologue narration
}

pack_phonetics() {
  printf '%s\n' \
    phoneme phone phonetics phonology vowel consonant syllable \
    stress intonation pitch rhythm diphthong monophthong allophone \
    prosody accent articulation manner place_of_articulation \
    bilabial alveolar velar glottal fricative plosive nasal \
    liquid glide schwa mora onset coda nucleus rhyme_scheme \
    IPA transcription pronunciation accent_mark liaison
}

pack_metaphor() {
  printf '%s\n' \
    bridge seed flame river mountain root crown mirror vessel \
    garden horizon forge loom thread weave constellation lighthouse \
    compass anchor harbor pathway doorway threshold keystone \
    scaffold lattice latticework tapestry mosaic prism lens \
    spring wellspring fountain current eddy tide shore \
    spark ember kindling hearth anvil hammer chisel polish \
    bloom blossom fruit harvest orchard meadow canopy
}

pack_acronym() {
  # desk + speech acronyms Hostess already loves · expand gently
  printf '%s\n' \
    bgs bgf bgl sdf spv rtx gpu cpu api dns tcp udp ssh ssl tls \
    asm nasm elf pdf png jpg gif csv tsv xml json html \
    h7 si av os ram vram hdmi usb ssd avx pci \
    spv_free full_127 never_ml c_is_lie free_thrift \
    word_end iron_rhyme pure_linear until_grin self_code self_learn
}

pack_thesaurus() {
  # bridges + quality synonym clouds (English ↔ iron)
  printf '%s\n' \
    field distance gap delta present active physics ground \
    free random salt spice noise entropy mix thrift \
    truth know real sure forward confidence certainty \
    time clock epoch stamp tick refresh tempo duration \
    space place dimension volume region locale site \
    heat warm cool thermo temp band thermal climate \
    see view display screen vision gaze glance watch \
    hear audio sound play listen tone melody resonance \
    net send recv wire link connect route packet stream \
    memory load store buffer cache hold retain recall \
    live have remain inside outside secure clean clear \
    measure travel read learn teach code language speech \
    love whole internet resolute soft_clear war_machine
}

pack_dict_sample() {
  # sample real dictionary · quality filter · not dump 233k
  local dict="/usr/share/dict/words"
  [[ -f "$dict" ]] || dict="/usr/share/dict/american-english"
  [[ -f "$dict" ]] || { echo "language"; return; }
  # prefer common-ish lengths · alphabetic lower
  grep -E '^[a-z]{4,12}$' "$dict" 2>/dev/null \
    | awk 'NR%17==0' \
    | head -n 400 || true
}

emit_pack() {
  local track="$1"
  shift
  local w
  while IFS= read -r w; do
    [[ -z "$w" ]] && continue
    w=$(printf '%s' "$w" | tr '[:upper:]' '[:lower:]' | tr -cd 'a-z0-9_')
    ok_word "$w" || continue
    printf '%s\t%s\t%s\n' "$w" "$track" "lang pack $track"
  done
}

build_curriculum() {
  # keep pack order · do NOT alpha-sort (DICT would crowd grammar)
  {
    pack_grammar   | emit_pack GRAMMAR
    pack_diction   | emit_pack DICTION
    pack_phonetics | emit_pack PHONETICS
    pack_metaphor  | emit_pack METAPHOR
    pack_acronym   | emit_pack ACRONYM
    pack_thesaurus | emit_pack THESAURUS
    pack_dict_sample | emit_pack DICT
  } | awk -F'\t' 'NF>=2 && !seen[$1]++' >"$CURRIC"
  say "curriculum rows=$(wc -l <"$CURRIC" | tr -d ' ')"
}

# punch quality words into Hostess vocab (leading weakness)
# round-robin tracks so grammar/diction/phonetics get fair share
punch() {
  build_curriculum
  [[ -f "$VOCAB" ]] || : >"$VOCAB"
  local known="$FAST/vocab_known_lang.txt"
  cut -f1 "$VOCAB" 2>/dev/null | tr '[:upper:]' '[:lower:]' | LC_ALL=C sort -u >"$known"
  local n_add=0 n_skip=0 n_rej=0
  local limit="$BATCH"
  : >"$FAST/lang_punch.partial"

  # per-track quota · fair punch
  local per=$(( limit / 7 + 1 ))
  local t
  for t in GRAMMAR DICTION PHONETICS METAPHOR ACRONYM THESAURUS DICT; do
    local t_add=0
    while IFS=$'\t' read -r w track note; do
      [[ "$track" == "$t" ]] || continue
      [[ -z "$w" ]] && continue
      if grep -qxF "$w" "$known" 2>/dev/null; then
        n_skip=$((n_skip + 1))
        continue
      fi
      if ! ok_word "$w"; then
        n_rej=$((n_rej + 1))
        continue
      fi
      local kind="$t"
      printf '%s\t%s\t%s\t%s\t%s\n' "$w" "_lang" "$kind" "1" "$note" >>"$FAST/lang_punch.partial"
      printf '%s\t%s\t%s\t%s\n' "$TS" "$w" "$kind" "learn" >>"$GROWTH"
      printf '%s\t%s\t%s\t%s\n' "$TS" "$w" "$kind" "learn" >>"$FEED"
      echo "$w" >>"$known"
      n_add=$((n_add + 1))
      t_add=$((t_add + 1))
      (( t_add >= per )) && break
      (( n_add >= limit )) && break
    done <"$CURRIC"
    (( n_add >= limit )) && break
  done

  if [[ -s "$FAST/lang_punch.partial" ]]; then
    cat "$FAST/lang_punch.partial" >>"$VOCAB"
    LC_ALL=C sort -t$'\t' -k1,1 -u "$VOCAB" -o "$VOCAB"
  fi

  # push remaining curriculum into work queue front (no SIGPIPE death)
  if [[ -f "$WORKQ" ]]; then
    local qtmp
    qtmp=$(mktemp)
    awk -F'\t' 'NF{print $1}' "$CURRIC" \
      | while read -r w; do
          grep -qxF "$w" "$known" 2>/dev/null && continue
          ok_word "$w" && echo "$w"
        done >"$qtmp" || true
    if [[ -s "$qtmp" ]]; then
      { head -n 200 "$qtmp" || true; cat "$WORKQ"; } | awk 'NF && !s[$0]++' >"${WORKQ}.new" || true
      mv "${WORKQ}.new" "$WORKQ" 2>/dev/null || true
    fi
    rm -f "$qtmp"
  fi

  write_report "$n_add" "$n_skip" "$n_rej"
  say "PUNCH · added=$n_add skip=$n_skip rej=$n_rej vocab=$(wc -l <"$VOCAB" | tr -d ' ')"
  cat "$JSON"
}

write_report() {
  local n_add="${1:-0}" n_skip="${2:-0}" n_rej="${3:-0}"
  local vocab_n=0 correct=0
  [[ -f "$VOCAB" ]] && vocab_n=$(wc -l <"$VOCAB" | tr -d ' ')
  [[ -f "$VOCAB" ]] && correct=$(awk -F'\t' '$4==1{c++} END{print c+0}' "$VOCAB")
  local curr_n=0
  [[ -f "$CURRIC" ]] && curr_n=$(wc -l <"$CURRIC" | tr -d ' ')

  # coverage per track in vocab
  local cov
  cov=$(python3 - "$VOCAB" "$CURRIC" <<'PY'
import sys,collections
vocab_path, curr_path = sys.argv[1], sys.argv[2]
known=set()
kinds=collections.Counter()
try:
  for line in open(vocab_path,encoding="utf-8",errors="replace"):
    p=line.rstrip("\n").split("\t")
    if len(p)>=3:
      known.add(p[0].lower())
      kinds[p[2]]+=1
except FileNotFoundError:
  pass
tracks=["GRAMMAR","DICTION","PHONETICS","METAPHOR","ACRONYM","THESAURUS","DICT"]
curr=collections.defaultdict(list)
try:
  for line in open(curr_path,encoding="utf-8",errors="replace"):
    p=line.rstrip("\n").split("\t")
    if len(p)>=2: curr[p[1]].append(p[0].lower())
except FileNotFoundError:
  pass
out={}
for t in tracks:
  words=curr.get(t,[])
  have=sum(1 for w in words if w in known)
  out[t]={"pool":len(words),"have":have,"pct": round(100*have/max(1,len(words)),1)}
# also count kinds already in vocab
out["_kinds_in_vocab"]={k:int(v) for k,v in kinds.items() if k in tracks or k in ("EDUCATION","LIMB","FOUNDATION")}
import json
print(json.dumps(out))
PY
)

  cat >"$JSON" <<EOF
{
  "ts": "$TS",
  "word": "H7_LANGUAGE_LEARN",
  "she": "Hostess 7",
  "ok": true,
  "vocab_N": $vocab_n,
  "vocab_correct": $correct,
  "curriculum_pool": $curr_n,
  "last_punch": {"added": $n_add, "skip": $n_skip, "reject": $n_rej, "batch": $BATCH},
  "tracks": $cov,
  "needs": {
    "full_dictionary": "sampled not dumped · 233k dict_corpus.asm exists · iron filter gate",
    "thesaurus": "bridges.asm 13 groups + pack expand · more synonym clouds yes",
    "metaphors": "pack live · figure speech for field love",
    "acronyms": "desk pins + speech pack · not thrash alphabet soup",
    "grammar": "pack live · structure of speech",
    "diction": "pack live · quality of word choice",
    "phonetics": "pack live · sound of speech"
  },
  "where_we_at": "quality curriculum punching · not full dict thrash · Hostess filters every word",
  "next": "densify grammar/diction/phonetics/metaphor to 80%+ pack coverage · Grok assist proposes · hold vocab quality",
  "law": "language is field to love · quality speech · iron accept · never ML ground · God Bless"
}
EOF
}

queue_only() {
  build_curriculum
  write_report 0 0 0
  say "queue/curriculum ready · pool=$(wc -l <"$CURRIC" | tr -d ' ')"
  cat "$JSON"
}

status() {
  if [[ -f "$JSON" ]]; then cat "$JSON"; else say "no report · run punch|once"; fi
  echo "--- vocab ---"
  [[ -f "$VOCAB" ]] && awk -F'\t' '$4==1{c++} END{print "correct",c+0}' "$VOCAB"
  [[ -f "$VOCAB" ]] && awk -F'\t' '{k[$3]++} END{for(i in k) print k[i],i}' "$VOCAB" | sort -rn | head -20
}

case "$cmd" in
  punch|once) punch ;;
  queue|build) queue_only ;;
  status|report) status ;;
  *)
    echo "usage: $0 punch|once|queue|status" >&2
    echo "  quality language curriculum · punch leading vocab weakness" >&2
    exit 2
    ;;
esac
