// morphology-peo.el - Old Persian morphology for the NLG engine.
//
// Implements Old Persian verb conjugation and noun declension for the ca. 600-300 BCE
// period (Achaemenid Empire).  Designed as a companion to morphology.el and called
// by the engine when the language profile code is "peo".
//
// Language profile: code=peo, name=Old Persian, morph_type=fusional, word_order=SOV,
//   question_strategy=particle, script=latin, family=iranian.
//
// Old Persian is attested primarily in royal cuneiform inscriptions (Behistun,
// Persepolis, Naqsh-e Rostam, etc.).  The transliteration used here follows the
// standard scholarly convention with macrons for long vowels (ā, ī, ū).  The corpus
// is small — most productive forms are individually attested in the inscriptions.
//
// Verb conjugation covered:
//   Tenses:   present, past (imperfect)
//   Persons:  first/second/third x singular/plural (slots 0-5)
//   Irregulars: ah- (to be), kar- (to do/make), xšāya- (to rule),
//               tar- (to cross/overcome), dā- (to give)
//   Canonical map: "be" -> "ah-"
//   Pro-drop: the subject pronoun is typically omitted; the engine provides
//             conjugated forms only and does not add pronouns.
//
// Noun declension covered:
//   a-stem masculine (like "dahyu" — country/land)
//   Cases: nominative, accusative, genitive, dative x singular, plural
//   (Many case distinctions collapsed in practice; 4 cases implemented)
//   Articles: none — Old Persian has no article system
//
// Depends on: morphology.el (str_eq, str_len, str_slice, str_ends_with)

// ── String helpers ─────────────────────────────────────────────────────────────

import "morphology.el"
fn peo_drop(s: String, n: Int) -> String {
    let len: Int = str_len(s)
    if n >= len { return "" }
    return str_slice(s, 0, len - n)
}

fn peo_ends(s: String, suf: String) -> Bool {
    return str_ends_with(s, suf)
}

// ── Person/number slot ─────────────────────────────────────────────────────────
//
// Maps person x number to a 0-based paradigm slot.
//   0 = 1st singular   (adam)
//   1 = 2nd singular   (tuvam)
//   2 = 3rd singular   (hauv)
//   3 = 1st plural     (vayam)
//   4 = 2nd plural     (yuvam)
//   5 = 3rd plural     (taiy)

fn peo_slot(person: String, number: String) -> Int {
    if str_eq(person, "first") {
        if str_eq(number, "singular") { return 0 }
        return 3
    }
    if str_eq(person, "second") {
        if str_eq(number, "singular") { return 1 }
        return 4
    }
    // third
    if str_eq(number, "singular") { return 2 }
    return 5
}

// ── Regular present endings ────────────────────────────────────────────────────
//
// Old Persian present active indicative endings (Schmitt 1991 reconstruction):
//   Sg: 1st -āmiy   2nd -ahiy   3rd -atiy
//   Pl: 1st -āmahy  2nd -ātā    3rd -antiy
//
// These attach to the present stem.  The present stem typically equals the
// verbal root (sometimes with a thematic vowel -a-).

fn peo_present_suffix(slot: Int) -> String {
    if slot == 0 { return "āmiy" }
    if slot == 1 { return "ahiy" }
    if slot == 2 { return "atiy" }
    if slot == 3 { return "āmahy" }
    if slot == 4 { return "ātā" }
    return "antiy"
}

// ── Regular past (imperfect) endings ──────────────────────────────────────────
//
// Old Persian imperfect (past) endings.  The imperfect is formed with the augment
// a- prefixed to the stem, but since many verbs in the inscriptions appear without
// the augment or with it fossilised, the engine omits the augment prefix and
// returns only the stem + ending combination.
//
// Imperfect endings:
//   Sg: 1st -am   2nd -ā   3rd -a
//   Pl: 1st -āmā  2nd -ātā  3rd -ā

fn peo_past_suffix(slot: Int) -> String {
    if slot == 0 { return "am" }
    if slot == 1 { return "ā" }
    if slot == 2 { return "a" }
    if slot == 3 { return "āmā" }
    if slot == 4 { return "ātā" }
    return "ā"
}

// ── Irregular verb tables ──────────────────────────────────────────────────────

// ah- (to be) — the Old Persian verb for being/existence
//   Present: amiy, ahiy, astiy, amahy, astā, hatiy
//   Past:    āham, āha, āha, āhama, āhata, āhan

fn peo_ah_present(slot: Int) -> String {
    if slot == 0 { return "amiy" }
    if slot == 1 { return "ahiy" }
    if slot == 2 { return "astiy" }
    if slot == 3 { return "amahy" }
    if slot == 4 { return "astā" }
    return "hatiy"
}

fn peo_ah_past(slot: Int) -> String {
    if slot == 0 { return "āham" }
    if slot == 1 { return "āha" }
    if slot == 2 { return "āha" }
    if slot == 3 { return "āhama" }
    if slot == 4 { return "āhata" }
    return "āhan"
}

// kar- (to do/make) — highly productive verb, uses present stem kun-/kunav-
//   Present: kunāmiy, kunāhiy, kunautiy, kunāmahy, kunātā, kunavantiy
//   Past: akunavam (1sg), akunava (3sg) — limited attestation; simplified

fn peo_kar_present(slot: Int) -> String {
    if slot == 0 { return "kunāmiy" }
    if slot == 1 { return "kunāhiy" }
    if slot == 2 { return "kunautiy" }
    if slot == 3 { return "kunāmahy" }
    if slot == 4 { return "kunātā" }
    return "kunavantiy"
}

fn peo_kar_past(slot: Int) -> String {
    if slot == 0 { return "akunavam" }
    if slot == 1 { return "akunavā" }
    if slot == 2 { return "akunava" }
    if slot == 3 { return "akunavāmā" }
    if slot == 4 { return "akunavātā" }
    return "akunavan"
}

// xšāya- (to rule) — verb of the royal inscriptions, thematic stem xšāya-
//   Present: xšāyāmiy, xšāyāhiy, xšāyatiy, xšāyāmahy, xšāyātā, xšāyantiy

fn peo_xsaya_present(slot: Int) -> String {
    if slot == 0 { return "xšāyāmiy" }
    if slot == 1 { return "xšāyāhiy" }
    if slot == 2 { return "xšāyatiy" }
    if slot == 3 { return "xšāyāmahy" }
    if slot == 4 { return "xšāyātā" }
    return "xšāyantiy"
}

// tar- (to cross/overcome) — limited attestation in inscriptions
//   Attested: taratiy (3sg pres), tarantiy (3pl pres)
//   Other slots approximated using regular present endings on stem tar-

fn peo_tar_present(slot: Int) -> String {
    if slot == 2 { return "taratiy" }
    if slot == 5 { return "tarantiy" }
    // Other slots: apply regular endings to stem tar-
    return "tar" + peo_present_suffix(slot)
}

// dā- (to give) — long-vowel root, contracts in some forms
//   Present: dāmiy, dāhiy, dātiy, dāmahy, dātā, dantiy

fn peo_da_present(slot: Int) -> String {
    if slot == 0 { return "dāmiy" }
    if slot == 1 { return "dāhiy" }
    if slot == 2 { return "dātiy" }
    if slot == 3 { return "dāmahy" }
    if slot == 4 { return "dātā" }
    return "dantiy"
}

fn peo_da_past(slot: Int) -> String {
    if slot == 0 { return "adām" }
    if slot == 1 { return "adāā" }
    if slot == 2 { return "adā" }
    if slot == 3 { return "adāmā" }
    if slot == 4 { return "adātā" }
    return "adān"
}

// ── Canonical verb mapping ─────────────────────────────────────────────────────
//
// Maps English semantic labels to Old Persian verbal stems / citation forms.

fn peo_map_canonical(verb: String) -> String {
    if str_eq(verb, "be")    { return "ah" }
    if str_eq(verb, "do")    { return "kar" }
    if str_eq(verb, "make")  { return "kar" }
    if str_eq(verb, "rule")  { return "xšāya" }
    if str_eq(verb, "cross") { return "tar" }
    if str_eq(verb, "give")  { return "dā" }
    return verb
}

// ── peo_conjugate: main conjugation entry point ───────────────────────────────
//
// verb:   Old Persian verbal stem or English canonical label
// tense:  "present" | "past"
// person: "first" | "second" | "third"
// number: "singular" | "plural"
//
// Returns the inflected form.  Pro-drop language — the engine produces conjugated
// verb forms only; subject pronouns are omitted unless explicitly generated by
// the semantic layer.

fn peo_conjugate(verb: String, tense: String, person: String, number: String) -> String {
    let v: String = peo_map_canonical(verb)
    let slot: Int = peo_slot(person, number)

    // ── ah- (to be) ───────────────────────────────────────────────────────────
    if str_eq(v, "ah") {
        if str_eq(tense, "present") { return peo_ah_present(slot) }
        if str_eq(tense, "past")    { return peo_ah_past(slot) }
        return v
    }

    // ── kar- (to do/make) ─────────────────────────────────────────────────────
    if str_eq(v, "kar") {
        if str_eq(tense, "present") { return peo_kar_present(slot) }
        if str_eq(tense, "past")    { return peo_kar_past(slot) }
        return v
    }

    // ── xšāya- (to rule) ──────────────────────────────────────────────────────
    if str_eq(v, "xšāya") {
        if str_eq(tense, "present") { return peo_xsaya_present(slot) }
        // Past of xšāya-: apply imperfect endings to xšāya- stem
        if str_eq(tense, "past") { return "xšāya" + peo_past_suffix(slot) }
        return v
    }

    // ── tar- (to cross/overcome) ──────────────────────────────────────────────
    if str_eq(v, "tar") {
        if str_eq(tense, "present") { return peo_tar_present(slot) }
        if str_eq(tense, "past")    { return "tar" + peo_past_suffix(slot) }
        return v
    }

    // ── dā- (to give) ─────────────────────────────────────────────────────────
    if str_eq(v, "dā") {
        if str_eq(tense, "present") { return peo_da_present(slot) }
        if str_eq(tense, "past")    { return peo_da_past(slot) }
        return v
    }

    // ── Regular thematic verb ─────────────────────────────────────────────────
    //
    // Apply present or past endings directly to the stem.  The stem is assumed
    // to be in the form supplied (Old Persian thematic stems typically end in -a-).
    if str_eq(tense, "present") { return v + peo_present_suffix(slot) }
    if str_eq(tense, "past")    { return v + peo_past_suffix(slot) }

    // Unknown tense: return the bare stem
    return v
}

// ── a-stem masculine declension ("dahyu" — country/land) ─────────────────────
//
// The a-stem is the primary masculine nominal class in Old Persian.  The paradigm
// below uses "dahyu" (country, land — the most frequent noun in the inscriptions)
// as the fully specified exemplar.
//
// Singular:  nom dahyāuš   acc dahyum    gen dahyāuš   dat dahyavā
// Plural:    nom dahyāva   acc dahyūn    gen dahyūnām  dat dahyubiyā
//
// The singular nom/gen syncretism (both dahyāuš) is historically inherited from
// Old Iranian; it is not a scribal error.

fn peo_decline_astem(noun: String, gram_case: String, number: String) -> String {
    if str_eq(noun, "dahyu") {
        if str_eq(number, "singular") {
            if str_eq(gram_case, "nominative") { return "dahyāuš" }
            if str_eq(gram_case, "accusative") { return "dahyum" }
            if str_eq(gram_case, "genitive")   { return "dahyāuš" }
            if str_eq(gram_case, "dative")     { return "dahyavā" }
            return "dahyāuš"
        }
        if str_eq(gram_case, "nominative") { return "dahyāva" }
        if str_eq(gram_case, "accusative") { return "dahyūn" }
        if str_eq(gram_case, "genitive")   { return "dahyūnām" }
        if str_eq(gram_case, "dative")     { return "dahyubiyā" }
        return "dahyāva"
    }

    // Generic a-stem masculine: apply Old Persian nominal endings to base.
    // Base form assumed to be the uninflected stem (without final -u/-a).
    if str_eq(number, "singular") {
        if str_eq(gram_case, "nominative") { return noun + "āuš" }
        if str_eq(gram_case, "accusative") { return noun + "am" }
        if str_eq(gram_case, "genitive")   { return noun + "āuš" }
        if str_eq(gram_case, "dative")     { return noun + "avā" }
        return noun + "āuš"
    }
    // plural
    if str_eq(gram_case, "nominative") { return noun + "āva" }
    if str_eq(gram_case, "accusative") { return noun + "ūn" }
    if str_eq(gram_case, "genitive")   { return noun + "ūnām" }
    if str_eq(gram_case, "dative")     { return noun + "ubiyā" }
    return noun + "āva"
}

// ── peo_decline: main declension entry point ──────────────────────────────────
//
// noun:      Old Persian noun (nominative singular or uninflected stem)
// gram_case: "nominative" | "accusative" | "genitive" | "dative"
// number:    "singular" | "plural"
//
// Only the a-stem masculine paradigm is currently implemented; other stem classes
// fall back to the nominative singular form.  The corpus is small enough that
// most attested nouns are a-stems or i-stems whose oblique forms can be
// approximated by the a-stem pattern.

fn peo_decline(noun: String, gram_case: String, number: String) -> String {
    return peo_decline_astem(noun, gram_case, number)
}

// ── peo_noun_phrase: noun phrase builder ──────────────────────────────────────
//
// Old Persian has no definite or indefinite articles.  Definiteness was expressed
// contextually or through word order, not morphologically.  This function ignores
// the "definite" parameter and returns the declined noun form directly.
//
// noun:      Old Persian noun (nominative singular or stem)
// gram_case: "nominative" | "accusative" | "genitive" | "dative"
// number:    "singular" | "plural"
// definite:  "true" | "false" (ignored — no articles in Old Persian)
//
// Returns the declined noun form.

fn peo_noun_phrase(noun: String, gram_case: String, number: String, definite: String) -> String {
    return peo_decline(noun, gram_case, number)
}
