// language-profile.el - Language profile data and accessors.
//
// A language profile is a slot map ([String] key-value list) describing the
// typological properties of a natural language.  The engine reads these
// properties to drive morphology, word-order, and question-formation without
// any per-language code paths.
//
// Profile slot keys:
//   code        - ISO 639-1 code: "en", "ja", "ar", "zh", "de", "fr", "es", "sw", "hi", "ru", etc.
//   word_order  - "SVO" | "SOV" | "VSO" | "VOS" | "OVS" | "OSV" | "free"
//   morph_type  - "isolating" | "agglutinative" | "fusional" | "polysynthetic"
//   has_case    - "true" | "false"
//   has_gender  - "true" | "false"
//   script_dir  - "ltr" | "rtl" | "ttb"
//   agreement   - semicolon-separated features: "number;person" | "number;person;gender;case" | "none"
//   null_subject - "true" | "false"   (pro-drop: subject may be omitted)

// ── Constructor ───────────────────────────────────────────────────────────────

fn lang_profile(code: String, word_order: String, morph_type: String, has_case: String, has_gender: String, script_dir: String, agreement: String, null_subject: String) -> [String] {
    let r: [String] = native_list_empty()
    let r = native_list_append(r, "code")
    let r = native_list_append(r, code)
    let r = native_list_append(r, "word_order")
    let r = native_list_append(r, word_order)
    let r = native_list_append(r, "morph_type")
    let r = native_list_append(r, morph_type)
    let r = native_list_append(r, "has_case")
    let r = native_list_append(r, has_case)
    let r = native_list_append(r, "has_gender")
    let r = native_list_append(r, has_gender)
    let r = native_list_append(r, "script_dir")
    let r = native_list_append(r, script_dir)
    let r = native_list_append(r, "agreement")
    let r = native_list_append(r, agreement)
    let r = native_list_append(r, "null_subject")
    let r = native_list_append(r, null_subject)
    return r
}

// ── Accessor ──────────────────────────────────────────────────────────────────

fn lang_get(profile: [String], key: String) -> String {
    let n: Int = native_list_len(profile)
    let i: Int = 0
    while i < n - 1 {
        let k: String = native_list_get(profile, i)
        if str_eq(k, key) {
            return native_list_get(profile, i + 1)
        }
        let i = i + 2
    }
    return ""
}

// ── Built-in profiles ─────────────────────────────────────────────────────────
//
// Each profile encodes typological facts about one language.  These are data,
// not separate code paths.  Adding a new language means adding a new profile
// and loading its vocabulary/suffix tables into the Engram - no engine changes.

// English: SVO, fusional, no grammatical case (nominative/accusative collapsed),
// no grammatical gender, left-to-right, agreement on number and person,
// obligatory subject (no pro-drop).
fn lang_profile_en() -> [String] {
    return lang_profile("en", "SVO", "fusional", "false", "false", "ltr", "number;person", "false")
}

// Japanese: SOV, agglutinative, grammatical relations marked by postpositions
// (not inflectional case), no grammatical gender, left-to-right, no agreement
// morphology on verbs, pro-drop (null subject frequent).
fn lang_profile_ja() -> [String] {
    return lang_profile("ja", "SOV", "agglutinative", "false", "false", "ltr", "none", "true")
}

// Arabic: VSO, fusional, full case system, grammatical gender (masc/fem),
// right-to-left script, agreement on number, person, gender, and case,
// pro-drop (subject agreement marking on verb allows subject omission).
fn lang_profile_ar() -> [String] {
    return lang_profile("ar", "VSO", "fusional", "true", "true", "rtl", "number;person;gender;case", "true")
}

// Mandarin Chinese: SVO, isolating (no morphological inflection), no case,
// no grammatical gender, left-to-right, no agreement (no morphological marking),
// null subject allowed in discourse context.
fn lang_profile_zh() -> [String] {
    return lang_profile("zh", "SVO", "isolating", "false", "false", "ltr", "none", "true")
}

// German: V2 (second-position verb, base SOV in subordinate clauses), fusional,
// four-case system, three grammatical genders, left-to-right, agreement on
// number, person, gender, and case, obligatory subject.
fn lang_profile_de() -> [String] {
    return lang_profile("de", "SOV", "fusional", "true", "true", "ltr", "number;person;gender;case", "false")
}

// Spanish: SVO, fusional, no morphological case (but object clitics exist),
// grammatical gender (masc/fem), left-to-right, agreement on number, person,
// and gender, pro-drop (rich verbal agreement allows subject omission).
fn lang_profile_es() -> [String] {
    return lang_profile("es", "SVO", "fusional", "false", "true", "ltr", "number;person;gender", "true")
}

// Finnish: SOV, agglutinative, fifteen grammatical cases, no grammatical gender,
// left-to-right, agreement on number, person, and case, no pro-drop (subject
// required in finite clauses).
fn lang_profile_fi() -> [String] {
    return lang_profile("fi", "SOV", "agglutinative", "true", "false", "ltr", "number;person;case", "false")
}

// Swahili: SVO, agglutinative, noun-class system (15+ classes replacing gender),
// no case inflection, left-to-right, agreement driven by noun class and number,
// pro-drop (subject prefix on verb can stand alone).
fn lang_profile_sw() -> [String] {
    return lang_profile("sw", "SVO", "agglutinative", "false", "false", "ltr", "noun-class;number", "true")
}

// Hindi: SOV, fusional, case-marked postpositional system, grammatical gender
// (masc/fem), left-to-right (Devanagari script still ltr), agreement on number,
// person, gender, and case, pro-drop (subject frequently dropped).
fn lang_profile_hi() -> [String] {
    return lang_profile("hi", "SOV", "fusional", "true", "true", "ltr", "number;person;gender;case", "true")
}

// Russian: free word order (pragmatically determined), fusional, six-case system,
// three grammatical genders, left-to-right (Cyrillic), agreement on number,
// person, gender, and case, no pro-drop (subject required).
fn lang_profile_ru() -> [String] {
    return lang_profile("ru", "free", "fusional", "true", "true", "ltr", "number;person;gender;case", "false")
}

// French: SVO, fusional, no morphological case (but clitic object pronouns),
// two grammatical genders (masc/fem), left-to-right, agreement on number,
// person, and gender, no pro-drop.
fn lang_profile_fr() -> [String] {
    return lang_profile("fr", "SVO", "fusional", "false", "true", "ltr", "number;person;gender", "false")
}

// Latin: SOV (highly free word order), fusional, six-case system (nom/gen/dat/acc/abl/voc),
// three genders (masc/fem/neut), left-to-right, rich agreement on number, person, gender,
// and case, pro-drop (subject expressed in verb ending).
fn lang_profile_la() -> [String] {
    return lang_profile("la", "SOV", "fusional", "true", "true", "ltr", "number;person;gender;case", "true")
}

// Hebrew (Modern): SVO, Semitic trilateral root morphology, two genders (masc/fem),
// two numbers (singular/plural; dual vestigial), right-to-left (Hebrew script),
// agreement on number, person, gender; zero copula in present tense; no grammatical cases.
fn lang_profile_he() -> [String] {
    return lang_profile("he", "SVO", "semitic", "true", "false", "rtl", "number;person;gender", "true")
}

// Sanskrit: SOV/free, highly fusional, 3 genders, 8 cases, 3 numbers (sg/du/pl),
// Devanagari script, rich verb system (10 classes, 9 tenses/moods), pro-drop.
fn lang_profile_sa() -> [String] {
    return lang_profile("sa", "SOV", "fusional", "true", "true", "ltr", "number;person;gender;case", "true")
}

// Gothic: SOV, fusional, 3 genders, 4 cases, singular/plural,
// Gothic alphabet (romanized as þ/ƕ/ai/au/ei), strong and weak classes, pro-drop.
fn lang_profile_got() -> [String] {
    return lang_profile("got", "SOV", "fusional", "true", "true", "ltr", "number;person;gender;case", "true")
}

// Old Norse: free/SOV, fusional, 3 genders, 4 cases, singular/plural,
// definite article as noun suffix (-inn/-in/-it), strong and weak classes, pro-drop.
fn lang_profile_non() -> [String] {
    return lang_profile("non", "SOV", "fusional", "true", "true", "ltr", "number;person;gender;case", "true")
}

// Middle English (ca. 1100–1500): SVO emerging, mostly lost case system,
// -es plural/genitive, strong and weak verbs, no grammatical gender on nouns.
fn lang_profile_enm() -> [String] {
    return lang_profile("enm", "SVO", "fusional", "false", "false", "ltr", "number;person", "false")
}

// Pali: SOV, fusional (simplified Sanskrit), 3 genders, 8 cases, sg/pl,
// Latin transliteration with IAST diacritics, Buddhist canonical language.
fn lang_profile_pi() -> [String] {
    return lang_profile("pi", "SOV", "fusional", "true", "true", "ltr", "number;person;gender;case", "true")
}

// Ancient Greek: free/SOV word order, highly fusional, 3 genders, 5 cases (nom/acc/gen/dat/voc),
// singular/dual/plural, polytonic Greek script (Unicode), complex verb system with aspect
// (imperfective/perfective), augment in past tenses, pro-drop.
fn lang_profile_grc() -> [String] {
    return lang_profile("grc", "SOV", "fusional", "true", "true", "ltr", "number;person;gender;case;aspect", "true")
}

// Old English (Anglo-Saxon): SOV/V2, fusional, 3 genders, 4 cases (nom/acc/gen/dat),
// singular/plural, Latin alphabet + þ/ð/ƿ/æ, strong and weak noun/verb classes, pro-drop.
fn lang_profile_ang() -> [String] {
    return lang_profile("ang", "SOV", "fusional", "true", "true", "ltr", "number;person;gender;case", "true")
}

// Old French (ca. 1000–1300 CE): SVO/V2, fusional, two-case system (nominative/oblique),
// two genders (masculine/feminine), left-to-right, agreement on number, person, gender,
// and case, no pro-drop (subject generally required).
fn lang_profile_fro() -> [String] {
    return lang_profile("fro", "SVO", "fusional", "true", "true", "ltr", "number;person;gender;case", "false")
}

// Old High German (ca. 750–1050 CE): SOV/V2, fusional, four-case system, three genders,
// left-to-right, agreement on number, person, gender, and case, pro-drop.
fn lang_profile_goh() -> [String] {
    return lang_profile("goh", "SOV", "fusional", "true", "true", "ltr", "number;person;gender;case", "true")
}

// Old Irish (ca. 600–900 CE): VSO, fusional, case system, three genders,
// left-to-right, agreement on number, person, gender, and case, pro-drop.
fn lang_profile_sga() -> [String] {
    return lang_profile("sga", "VSO", "fusional", "true", "true", "ltr", "number;person;gender;case", "true")
}

// Tocharian B (ca. 500–1000 CE): SOV, fusional, case system, two genders,
// left-to-right, agreement on number, person, gender, and case, no pro-drop.
fn lang_profile_txb() -> [String] {
    return lang_profile("txb", "SOV", "fusional", "true", "true", "ltr", "number;person;gender;case", "false")
}

// Old Persian (ca. 525–330 BCE): SOV, fusional, 8-case system, no grammatical gender,
// left-to-right, agreement on number, person, and case, pro-drop.
fn lang_profile_peo() -> [String] {
    return lang_profile("peo", "SOV", "fusional", "true", "false", "ltr", "number;person;case", "true")
}

// Akkadian (Old Babylonian period, ca. 1900–1600 BCE): VSO, fusional, 3-case system
// (nominative/accusative/genitive with mimation), two genders, left-to-right,
// agreement on number, person, gender, and case, no pro-drop.
fn lang_profile_akk() -> [String] {
    return lang_profile("akk", "VSO", "fusional", "true", "true", "ltr", "number;person;gender;case", "false")
}

// Ugaritic (ca. 1400–1200 BCE): VSO, Semitic trilateral root morphology, 3-case system,
// two genders, left-to-right (cuneiform alphabetic script), agreement on number, person,
// gender, and case, no pro-drop.
fn lang_profile_uga() -> [String] {
    return lang_profile("uga", "VSO", "semitic", "true", "true", "ltr", "number;person;gender;case", "false")
}

// Ancient Egyptian / Middle Egyptian (ca. 2100–1300 BCE): SVO, agglutinative,
// no morphological case (word order + prepositions), two genders, left-to-right,
// agreement on number, person, and gender, pro-drop (zero copula in present).
fn lang_profile_egy() -> [String] {
    return lang_profile("egy", "SVO", "agglutinative", "false", "true", "ltr", "number;person;gender", "true")
}

// Sumerian (ca. 3000–2000 BCE): SOV, agglutinative, ergative-absolutive case system,
// no grammatical gender (animacy distinction instead), left-to-right, agreement on
// number and person, pro-drop.
fn lang_profile_sux() -> [String] {
    return lang_profile("sux", "SOV", "agglutinative", "true", "false", "ltr", "number;person", "true")
}

// Ge'ez (Classical Ethiopic, ca. 4th–7th century CE): SOV, Semitic trilateral root
// morphology, two genders (masc/fem), Ethiopic/Fidel script (ltr), agreement on
// number, person, and gender, pro-drop (subject inflection on verb).
fn lang_profile_gez() -> [String] {
    return lang_profile("gez", "SOV", "semitic", "true", "true", "ltr", "number;person;gender", "true")
}

// Coptic (Sahidic dialect, ca. 3rd–11th century CE): SVO, agglutinative, no
// morphological case, two genders (masc/fem), left-to-right (Coptic alphabet),
// agreement on number and gender via bound subject pronouns, no pro-drop (explicit
// subject prefix required on every verb).
fn lang_profile_cop() -> [String] {
    return lang_profile("cop", "SVO", "agglutinative", "false", "true", "ltr", "number;person;gender", "false")
}

// ── Dispatch: code -> profile ─────────────────────────────────────────────────

fn lang_from_code(code: String) -> [String] {
    if str_eq(code, "en") { return lang_profile_en() }
    if str_eq(code, "ja") { return lang_profile_ja() }
    if str_eq(code, "ar") { return lang_profile_ar() }
    if str_eq(code, "zh") { return lang_profile_zh() }
    if str_eq(code, "de") { return lang_profile_de() }
    if str_eq(code, "es") { return lang_profile_es() }
    if str_eq(code, "fi") { return lang_profile_fi() }
    if str_eq(code, "sw") { return lang_profile_sw() }
    if str_eq(code, "hi") { return lang_profile_hi() }
    if str_eq(code, "ru") { return lang_profile_ru() }
    if str_eq(code, "fr") { return lang_profile_fr() }
    if str_eq(code, "la") { return lang_profile_la() }
    if str_eq(code, "he") { return lang_profile_he() }
    if str_eq(code, "grc") { return lang_profile_grc() }
    if str_eq(code, "ang") { return lang_profile_ang() }
    if str_eq(code, "sa")  { return lang_profile_sa()  }
    if str_eq(code, "got") { return lang_profile_got() }
    if str_eq(code, "non") { return lang_profile_non() }
    if str_eq(code, "enm") { return lang_profile_enm() }
    if str_eq(code, "pi")  { return lang_profile_pi()  }
    if str_eq(code, "fro") { return lang_profile_fro() }
    if str_eq(code, "goh") { return lang_profile_goh() }
    if str_eq(code, "sga") { return lang_profile_sga() }
    if str_eq(code, "txb") { return lang_profile_txb() }
    if str_eq(code, "peo") { return lang_profile_peo() }
    if str_eq(code, "akk") { return lang_profile_akk() }
    if str_eq(code, "uga") { return lang_profile_uga() }
    if str_eq(code, "egy") { return lang_profile_egy() }
    if str_eq(code, "sux") { return lang_profile_sux() }
    if str_eq(code, "gez") { return lang_profile_gez() }
    if str_eq(code, "cop") { return lang_profile_cop() }
    // Unknown code: fall back to English profile
    return lang_profile_en()
}

// English default - backward compatibility entry point.
fn lang_default() -> [String] {
    return lang_profile_en()
}

// ── Typed convenience predicates ──────────────────────────────────────────────

fn lang_is_isolating(profile: [String]) -> Bool {
    return str_eq(lang_get(profile, "morph_type"), "isolating")
}

fn lang_is_agglutinative(profile: [String]) -> Bool {
    return str_eq(lang_get(profile, "morph_type"), "agglutinative")
}

fn lang_is_fusional(profile: [String]) -> Bool {
    return str_eq(lang_get(profile, "morph_type"), "fusional")
}

fn lang_is_polysynthetic(profile: [String]) -> Bool {
    return str_eq(lang_get(profile, "morph_type"), "polysynthetic")
}

fn lang_is_rtl(profile: [String]) -> Bool {
    return str_eq(lang_get(profile, "script_dir"), "rtl")
}

fn lang_has_null_subject(profile: [String]) -> Bool {
    return str_eq(lang_get(profile, "null_subject"), "true")
}

fn lang_has_case(profile: [String]) -> Bool {
    return str_eq(lang_get(profile, "has_case"), "true")
}

fn lang_has_gender(profile: [String]) -> Bool {
    return str_eq(lang_get(profile, "has_gender"), "true")
}

fn lang_word_order(profile: [String]) -> String {
    return lang_get(profile, "word_order")
}

fn lang_code(profile: [String]) -> String {
    return lang_get(profile, "code")
}
