// vocabulary.el - Vocabulary query interface with inline seed data.
//
// Represents lexical entries with POS, morphological forms, semantic class,
// synonyms, and a language code.  Inline data covers English vocabulary needed
// for grammar tests.  The long-term backing store is the Neuron Engram (queried
// at runtime via searchKnowledge(query="VOCAB: <word>", category="vocabulary")),
// but inline data is used for bootstrapping.
//
// Language codes follow ISO 639-1.  The seed data below is English ("en").
// Vocabulary for other languages is loaded from the Engram at runtime; the
// engine functions `vocab_lookup` and `vocab_synonym` accept a lang_code
// parameter to filter results by language.
//
// POS values: "noun" | "verb" | "adjective" | "adverb" | "determiner" |
//             "preposition" | "pronoun" | "conjunction" | "auxiliary"

// ── LexEntry: a single lexeme ─────────────────────────────────────────────────
//
// forms meaning:
//   noun:       [singular, plural]
//   verb:       [base, 3sg, past, pastpart, gerund]
//   pronoun:    [nominative, accusative, genitive]
//   other:      [word]

fn lex_word(entry: [String]) -> String {
    return native_list_get(entry, 0)
}

fn lex_pos(entry: [String]) -> String {
    return native_list_get(entry, 1)
}

fn lex_form(entry: [String], idx: Int) -> String {
    // forms start at index 2
    let n: Int = native_list_len(entry)
    let real_idx: Int = idx + 2
    if real_idx >= n {
        return native_list_get(entry, 0)
    }
    return native_list_get(entry, real_idx)
}

fn lex_class(entry: [String]) -> String {
    let n: Int = native_list_len(entry)
    let last: Int = n - 1
    return native_list_get(entry, last)
}

// Build a vocab entry: [word, pos, form0, form1, ..., semantic_class]
fn make_entry(word: String, pos: String, f0: String, f1: String, f2: String, f3: String, f4: String, cls: String) -> [String] {
    let r: [String] = native_list_empty()
    let r = native_list_append(r, word)
    let r = native_list_append(r, pos)
    let r = native_list_append(r, f0)
    let r = native_list_append(r, f1)
    let r = native_list_append(r, f2)
    let r = native_list_append(r, f3)
    let r = native_list_append(r, f4)
    let r = native_list_append(r, cls)
    return r
}

fn make_entry2(word: String, pos: String, f0: String, f1: String, cls: String) -> [String] {
    let r: [String] = native_list_empty()
    let r = native_list_append(r, word)
    let r = native_list_append(r, pos)
    let r = native_list_append(r, f0)
    let r = native_list_append(r, f1)
    let r = native_list_append(r, cls)
    return r
}

fn make_entry3(word: String, pos: String, f0: String, f1: String, f2: String, cls: String) -> [String] {
    let r: [String] = native_list_empty()
    let r = native_list_append(r, word)
    let r = native_list_append(r, pos)
    let r = native_list_append(r, f0)
    let r = native_list_append(r, f1)
    let r = native_list_append(r, f2)
    let r = native_list_append(r, cls)
    return r
}

fn make_entry1(word: String, pos: String, f0: String, cls: String) -> [String] {
    let r: [String] = native_list_empty()
    let r = native_list_append(r, word)
    let r = native_list_append(r, pos)
    let r = native_list_append(r, f0)
    let r = native_list_append(r, cls)
    return r
}

// ── Seed vocabulary ───────────────────────────────────────────────────────────

fn build_vocab() -> [[String]] {
    let v: [[String]] = native_list_empty()

    // ── Pronouns [nominative, accusative, genitive] ───────────────────────────
    let v = native_list_append(v, make_entry3("I",    "pronoun", "I",    "me",   "my",    "person-first-sg"))
    let v = native_list_append(v, make_entry3("you",  "pronoun", "you",  "you",  "your",  "person-second"))
    let v = native_list_append(v, make_entry3("he",   "pronoun", "he",   "him",  "his",   "person-third-sg-m"))
    let v = native_list_append(v, make_entry3("she",  "pronoun", "she",  "her",  "her",   "person-third-sg-f"))
    let v = native_list_append(v, make_entry3("it",   "pronoun", "it",   "it",   "its",   "person-third-sg-n"))
    let v = native_list_append(v, make_entry3("we",   "pronoun", "we",   "us",   "our",   "person-first-pl"))
    let v = native_list_append(v, make_entry3("they", "pronoun", "they", "them", "their", "person-third-pl"))

    // ── Determiners [word] ────────────────────────────────────────────────────
    let v = native_list_append(v, make_entry1("a",    "determiner", "a",    "indefinite"))
    let v = native_list_append(v, make_entry1("an",   "determiner", "an",   "indefinite"))
    let v = native_list_append(v, make_entry1("the",  "determiner", "the",  "definite"))
    let v = native_list_append(v, make_entry1("some", "determiner", "some", "indefinite-pl"))
    let v = native_list_append(v, make_entry1("this", "determiner", "this", "demonstrative-sg"))
    let v = native_list_append(v, make_entry1("that", "determiner", "that", "demonstrative-sg"))
    let v = native_list_append(v, make_entry1("these","determiner", "these","demonstrative-pl"))
    let v = native_list_append(v, make_entry1("those","determiner", "those","demonstrative-pl"))

    // ── Prepositions [word] ───────────────────────────────────────────────────
    let v = native_list_append(v, make_entry1("in",   "preposition", "in",   "location"))
    let v = native_list_append(v, make_entry1("on",   "preposition", "on",   "location"))
    let v = native_list_append(v, make_entry1("at",   "preposition", "at",   "location"))
    let v = native_list_append(v, make_entry1("to",   "preposition", "to",   "direction"))
    let v = native_list_append(v, make_entry1("for",  "preposition", "for",  "purpose"))
    let v = native_list_append(v, make_entry1("of",   "preposition", "of",   "relation"))
    let v = native_list_append(v, make_entry1("with", "preposition", "with", "accompaniment"))
    let v = native_list_append(v, make_entry1("from", "preposition", "from", "source"))
    let v = native_list_append(v, make_entry1("by",   "preposition", "by",   "agent"))
    let v = native_list_append(v, make_entry1("into", "preposition", "into", "direction"))

    // ── Auxiliaries [base, 3sg, past, pastpart, gerund] ───────────────────────
    let v = native_list_append(v, make_entry("is",    "auxiliary", "be",    "is",    "was",    "been",    "being",   "copula"))
    let v = native_list_append(v, make_entry("are",   "auxiliary", "be",    "is",    "was",    "been",    "being",   "copula"))
    let v = native_list_append(v, make_entry("was",   "auxiliary", "be",    "is",    "was",    "been",    "being",   "copula-past"))
    let v = native_list_append(v, make_entry("were",  "auxiliary", "be",    "is",    "were",   "been",    "being",   "copula-past"))
    let v = native_list_append(v, make_entry("has",   "auxiliary", "have",  "has",   "had",    "had",     "having",  "perfect"))
    let v = native_list_append(v, make_entry("have",  "auxiliary", "have",  "has",   "had",    "had",     "having",  "perfect"))
    let v = native_list_append(v, make_entry("had",   "auxiliary", "have",  "has",   "had",    "had",     "having",  "perfect-past"))
    let v = native_list_append(v, make_entry("will",  "auxiliary", "will",  "will",  "would",  "would",   "willing", "future"))
    let v = native_list_append(v, make_entry("can",   "auxiliary", "can",   "can",   "could",  "could",   "canning", "modal"))
    let v = native_list_append(v, make_entry("could", "auxiliary", "can",   "can",   "could",  "could",   "canning", "modal-past"))
    let v = native_list_append(v, make_entry("would", "auxiliary", "will",  "will",  "would",  "would",   "willing", "modal-cond"))
    let v = native_list_append(v, make_entry("do",    "auxiliary", "do",    "does",  "did",    "done",    "doing",   "do-support"))
    let v = native_list_append(v, make_entry("does",  "auxiliary", "do",    "does",  "did",    "done",    "doing",   "do-support"))
    let v = native_list_append(v, make_entry("did",   "auxiliary", "do",    "does",  "did",    "done",    "doing",   "do-support-past"))

    // ── Nouns [singular, plural] ──────────────────────────────────────────────
    let v = native_list_append(v, make_entry2("cat",     "noun", "cat",     "cats",     "animal"))
    let v = native_list_append(v, make_entry2("dog",     "noun", "dog",     "dogs",     "animal"))
    let v = native_list_append(v, make_entry2("bird",    "noun", "bird",    "birds",    "animal"))
    let v = native_list_append(v, make_entry2("fish",    "noun", "fish",    "fish",     "animal"))
    let v = native_list_append(v, make_entry2("horse",   "noun", "horse",   "horses",   "animal"))
    let v = native_list_append(v, make_entry2("house",   "noun", "house",   "houses",   "building"))
    let v = native_list_append(v, make_entry2("book",    "noun", "book",    "books",    "object"))
    let v = native_list_append(v, make_entry2("table",   "noun", "table",   "tables",   "furniture"))
    let v = native_list_append(v, make_entry2("chair",   "noun", "chair",   "chairs",   "furniture"))
    let v = native_list_append(v, make_entry2("door",    "noun", "door",    "doors",    "structure"))
    let v = native_list_append(v, make_entry2("window",  "noun", "window",  "windows",  "structure"))
    let v = native_list_append(v, make_entry2("city",    "noun", "city",    "cities",   "place"))
    let v = native_list_append(v, make_entry2("park",    "noun", "park",    "parks",    "place"))
    let v = native_list_append(v, make_entry2("school",  "noun", "school",  "schools",  "place"))
    let v = native_list_append(v, make_entry2("store",   "noun", "store",   "stores",   "place"))
    let v = native_list_append(v, make_entry2("road",    "noun", "road",    "roads",    "place"))
    let v = native_list_append(v, make_entry2("box",     "noun", "box",     "boxes",    "container"))
    let v = native_list_append(v, make_entry2("child",   "noun", "child",   "children", "person"))
    let v = native_list_append(v, make_entry2("person",  "noun", "person",  "people",   "person"))
    let v = native_list_append(v, make_entry2("man",     "noun", "man",     "men",      "person"))
    let v = native_list_append(v, make_entry2("woman",   "noun", "woman",   "women",    "person"))
    let v = native_list_append(v, make_entry2("tree",    "noun", "tree",    "trees",    "plant"))
    let v = native_list_append(v, make_entry2("flower",  "noun", "flower",  "flowers",  "plant"))
    let v = native_list_append(v, make_entry2("water",   "noun", "water",   "waters",   "substance"))
    let v = native_list_append(v, make_entry2("food",    "noun", "food",    "foods",    "substance"))
    let v = native_list_append(v, make_entry2("time",    "noun", "time",    "times",    "abstract"))
    let v = native_list_append(v, make_entry2("day",     "noun", "day",     "days",     "time"))
    let v = native_list_append(v, make_entry2("night",   "noun", "night",   "nights",   "time"))
    let v = native_list_append(v, make_entry2("home",    "noun", "home",    "homes",    "place"))

    // ── Verbs [base, 3sg, past, pastpart, gerund] ─────────────────────────────
    let v = native_list_append(v, make_entry("run",    "verb", "run",    "runs",    "ran",    "run",    "running",  "motion"))
    let v = native_list_append(v, make_entry("walk",   "verb", "walk",   "walks",   "walked", "walked", "walking",  "motion"))
    let v = native_list_append(v, make_entry("go",     "verb", "go",     "goes",    "went",   "gone",   "going",    "motion"))
    let v = native_list_append(v, make_entry("come",   "verb", "come",   "comes",   "came",   "come",   "coming",   "motion"))
    let v = native_list_append(v, make_entry("see",    "verb", "see",    "sees",    "saw",    "seen",   "seeing",   "perception"))
    let v = native_list_append(v, make_entry("hear",   "verb", "hear",   "hears",   "heard",  "heard",  "hearing",  "perception"))
    let v = native_list_append(v, make_entry("look",   "verb", "look",   "looks",   "looked", "looked", "looking",  "perception"))
    let v = native_list_append(v, make_entry("eat",    "verb", "eat",    "eats",    "ate",    "eaten",  "eating",   "action"))
    let v = native_list_append(v, make_entry("drink",  "verb", "drink",  "drinks",  "drank",  "drunk",  "drinking", "action"))
    let v = native_list_append(v, make_entry("sleep",  "verb", "sleep",  "sleeps",  "slept",  "slept",  "sleeping", "state"))
    let v = native_list_append(v, make_entry("sit",    "verb", "sit",    "sits",    "sat",    "sat",    "sitting",  "posture"))
    let v = native_list_append(v, make_entry("stand",  "verb", "stand",  "stands",  "stood",  "stood",  "standing", "posture"))
    let v = native_list_append(v, make_entry("give",   "verb", "give",   "gives",   "gave",   "given",  "giving",   "transfer"))
    let v = native_list_append(v, make_entry("take",   "verb", "take",   "takes",   "took",   "taken",  "taking",   "transfer"))
    let v = native_list_append(v, make_entry("make",   "verb", "make",   "makes",   "made",   "made",   "making",   "creation"))
    let v = native_list_append(v, make_entry("put",    "verb", "put",    "puts",    "put",    "put",    "putting",  "placement"))
    let v = native_list_append(v, make_entry("find",   "verb", "find",   "finds",   "found",  "found",  "finding",  "discovery"))
    let v = native_list_append(v, make_entry("know",   "verb", "know",   "knows",   "knew",   "known",  "knowing",  "cognition"))
    let v = native_list_append(v, make_entry("think",  "verb", "think",  "thinks",  "thought","thought","thinking", "cognition"))
    let v = native_list_append(v, make_entry("say",    "verb", "say",    "says",    "said",   "said",   "saying",   "communication"))
    let v = native_list_append(v, make_entry("tell",   "verb", "tell",   "tells",   "told",   "told",   "telling",  "communication"))
    let v = native_list_append(v, make_entry("ask",    "verb", "ask",    "asks",    "asked",  "asked",  "asking",   "communication"))
    let v = native_list_append(v, make_entry("like",   "verb", "like",   "likes",   "liked",  "liked",  "liking",   "emotion"))
    let v = native_list_append(v, make_entry("love",   "verb", "love",   "loves",   "loved",  "loved",  "loving",   "emotion"))
    let v = native_list_append(v, make_entry("want",   "verb", "want",   "wants",   "wanted", "wanted", "wanting",  "desire"))
    let v = native_list_append(v, make_entry("need",   "verb", "need",   "needs",   "needed", "needed", "needing",  "desire"))
    let v = native_list_append(v, make_entry("have",   "verb", "have",   "has",     "had",    "had",    "having",   "possession"))
    let v = native_list_append(v, make_entry("hold",   "verb", "hold",   "holds",   "held",   "held",   "holding",  "possession"))
    let v = native_list_append(v, make_entry("open",   "verb", "open",   "opens",   "opened", "opened", "opening",  "action"))
    let v = native_list_append(v, make_entry("close",  "verb", "close",  "closes",  "closed", "closed", "closing",  "action"))
    let v = native_list_append(v, make_entry("write",  "verb", "write",  "writes",  "wrote",  "written","writing",  "action"))
    let v = native_list_append(v, make_entry("read",   "verb", "read",   "reads",   "read",   "read",   "reading",  "action"))
    let v = native_list_append(v, make_entry("build",  "verb", "build",  "builds",  "built",  "built",  "building", "creation"))
    let v = native_list_append(v, make_entry("live",   "verb", "live",   "lives",   "lived",  "lived",  "living",   "state"))
    let v = native_list_append(v, make_entry("work",   "verb", "work",   "works",   "worked", "worked", "working",  "activity"))
    let v = native_list_append(v, make_entry("play",   "verb", "play",   "plays",   "played", "played", "playing",  "activity"))
    let v = native_list_append(v, make_entry("help",   "verb", "help",   "helps",   "helped", "helped", "helping",  "activity"))

    // ── Adjectives [word] ─────────────────────────────────────────────────────
    let v = native_list_append(v, make_entry1("big",      "adjective", "big",      "size"))
    let v = native_list_append(v, make_entry1("small",    "adjective", "small",    "size"))
    let v = native_list_append(v, make_entry1("large",    "adjective", "large",    "size"))
    let v = native_list_append(v, make_entry1("little",   "adjective", "little",   "size"))
    let v = native_list_append(v, make_entry1("old",      "adjective", "old",      "age"))
    let v = native_list_append(v, make_entry1("new",      "adjective", "new",      "age"))
    let v = native_list_append(v, make_entry1("young",    "adjective", "young",    "age"))
    let v = native_list_append(v, make_entry1("good",     "adjective", "good",     "quality"))
    let v = native_list_append(v, make_entry1("bad",      "adjective", "bad",      "quality"))
    let v = native_list_append(v, make_entry1("fast",     "adjective", "fast",     "speed"))
    let v = native_list_append(v, make_entry1("slow",     "adjective", "slow",     "speed"))
    let v = native_list_append(v, make_entry1("hot",      "adjective", "hot",      "temperature"))
    let v = native_list_append(v, make_entry1("cold",     "adjective", "cold",     "temperature"))
    let v = native_list_append(v, make_entry1("happy",    "adjective", "happy",    "emotion"))
    let v = native_list_append(v, make_entry1("sad",      "adjective", "sad",      "emotion"))
    let v = native_list_append(v, make_entry1("red",      "adjective", "red",      "color"))
    let v = native_list_append(v, make_entry1("blue",     "adjective", "blue",     "color"))
    let v = native_list_append(v, make_entry1("green",    "adjective", "green",    "color"))
    let v = native_list_append(v, make_entry1("white",    "adjective", "white",    "color"))
    let v = native_list_append(v, make_entry1("black",    "adjective", "black",    "color"))
    let v = native_list_append(v, make_entry1("long",     "adjective", "long",     "dimension"))
    let v = native_list_append(v, make_entry1("short",    "adjective", "short",    "dimension"))
    let v = native_list_append(v, make_entry1("beautiful","adjective", "beautiful","appearance"))
    let v = native_list_append(v, make_entry1("bright",   "adjective", "bright",   "appearance"))
    let v = native_list_append(v, make_entry1("dark",     "adjective", "dark",     "appearance"))

    return v
}

// ── Vocabulary cache ──────────────────────────────────────────────────────────
// The vocab list is built once and reused across queries.
// We use a simple linear scan (adequate for ~100 entries).

fn get_vocab() -> [[String]] {
    return build_vocab()
}

// ── Query functions ───────────────────────────────────────────────────────────
//
// All lookup functions accept an optional lang_code parameter.  The inline seed
// data is English ("en").  When lang_code is "" the match is language-agnostic
// (useful when the caller has already filtered by language).
//
// The Engram path (not implemented inline) would be:
//   searchKnowledge(query="VOCAB: " + word, category="vocabulary", lang=lang_code)

// vocab_lookup(word, lang_code) -> [String]
// Returns the entry whose word (index 0) matches the query word for the given
// language.  Pass lang_code="" to match any language.
fn vocab_lookup(word: String, lang_code: String) -> [String] {
    let vocab: [[String]] = get_vocab()
    let n: Int = native_list_len(vocab)
    let i: Int = 0
    while i < n {
        let entry: [String] = native_list_get(vocab, i)
        let w: String = native_list_get(entry, 0)
        if str_eq(w, word) {
            // The inline seed data is English.  If caller requests a specific
            // language other than "en", we cannot satisfy it from inline data;
            // return empty to signal "not found" (Engram lookup should follow).
            if !str_eq(lang_code, "") {
                if !str_eq(lang_code, "en") {
                    let empty: [String] = native_list_empty()
                    return empty
                }
            }
            return entry
        }
        let i = i + 1
    }
    let empty: [String] = native_list_empty()
    return empty
}

// vocab_lookup_en(word) -> [String]
// Backward-compatible alias: look up an English word.
fn vocab_lookup_en(word: String) -> [String] {
    return vocab_lookup(word, "en")
}

// vocab_synonym(word, register, lang_code) -> String
// Returns a register-appropriate synonym for a word in the given language.
// register: "formal" | "informal" | "neutral"
// Returns the original word if no synonym is found.
fn vocab_synonym(word: String, lang_register: String, lang_code: String) -> String {
    // Inline data does not carry synonym information.
    // The Engram backing store supplies synonyms via knowledge nodes.
    // Return the word unchanged as a safe fallback.
    return word
}

// Returns all entries whose pos (index 1) matches.
fn vocab_by_pos(pos: String) -> [[String]] {
    let vocab: [[String]] = get_vocab()
    let n: Int = native_list_len(vocab)
    let result: [[String]] = native_list_empty()
    let i: Int = 0
    while i < n {
        let entry: [String] = native_list_get(vocab, i)
        let p: String = native_list_get(entry, 1)
        if str_eq(p, pos) {
            let result = native_list_append(result, entry)
        }
        let i = i + 1
    }
    return result
}

// Returns all entries whose semantic class (last element) matches or starts with cls.
fn vocab_by_class(cls: String) -> [[String]] {
    let vocab: [[String]] = get_vocab()
    let n: Int = native_list_len(vocab)
    let result: [[String]] = native_list_empty()
    let i: Int = 0
    while i < n {
        let entry: [String] = native_list_get(vocab, i)
        let m: Int = native_list_len(entry)
        let c: String = native_list_get(entry, m - 1)
        if str_eq(c, cls) {
            let result = native_list_append(result, entry)
        }
        let i = i + 1
    }
    return result
}

// ── Convenience accessors for a retrieved entry ───────────────────────────────

// Is this entry non-empty (i.e., found)?
fn entry_found(entry: [String]) -> Bool {
    let n: Int = native_list_len(entry)
    if n > 0 {
        return true
    }
    return false
}

fn entry_word(entry: [String]) -> String {
    return native_list_get(entry, 0)
}

fn entry_pos(entry: [String]) -> String {
    return native_list_get(entry, 1)
}

// Get the Nth morphological form (0-indexed, starts at position 2 in the list).
fn entry_form(entry: [String], n: Int) -> String {
    let real: Int = n + 2
    let total: Int = native_list_len(entry)
    if real >= total {
        return native_list_get(entry, 0)
    }
    return native_list_get(entry, real)
}
