// elp.el - Engram Language Protocol — public API.
//
// Output half of the ELP: Engram semantic form → natural language surface text.
// 31 languages. Ties together language-profile, vocabulary, morphology,
// grammar, realizer, and semantics into a single entry point.
//
// Import chain (mirrors manifest.el dependency order):
//   language-profile  (no deps)
//   vocabulary        (no deps)
//   morphology        (depends on: language-profile)
//   morphology-XX     (depends on: morphology)   — all language engines
//   grammar           (depends on: language-profile)
//   realizer          (depends on: morphology, grammar, language-profile)
//   semantics         (depends on: grammar, realizer, language-profile)
//
// When elc processes a source that imports this file, it resolves all
// transitive imports via depth-first deduplication — each module is
// inlined exactly once regardless of how many importers reference it.

// ── Base layers ───────────────────────────────────────────────────────────────
import "language-profile.el"
import "vocabulary.el"

// ── Morphology: base engine ───────────────────────────────────────────────────
import "morphology.el"

// ── Morphology: living languages ──────────────────────────────────────────────
import "morphology-es.el"
import "morphology-fr.el"
import "morphology-de.el"
import "morphology-ru.el"
import "morphology-ja.el"
import "morphology-fi.el"
import "morphology-ar.el"
import "morphology-hi.el"
import "morphology-sw.el"

// ── Morphology: ancient / classical ──────────────────────────────────────────
import "morphology-la.el"
import "morphology-he.el"

// ── Morphology: dead languages ────────────────────────────────────────────────
import "morphology-grc.el"
import "morphology-ang.el"
import "morphology-sa.el"
import "morphology-got.el"
import "morphology-non.el"
import "morphology-enm.el"
import "morphology-pi.el"
import "morphology-fro.el"
import "morphology-goh.el"
import "morphology-sga.el"
import "morphology-txb.el"
import "morphology-peo.el"
import "morphology-akk.el"
import "morphology-uga.el"
import "morphology-egy.el"
import "morphology-sux.el"
import "morphology-gez.el"
import "morphology-cop.el"

// ── Higher layers ─────────────────────────────────────────────────────────────
import "grammar.el"
import "realizer.el"
import "semantics.el"
//
// Entry points:
//
//   generate(semantic_form_json) -> String
//     Low-level JSON-based API, defaults to English.  SemanticForm JSON fields:
//       intent    - "assert" | "question" | "command"
//       agent     - subject (pronoun or noun phrase, optional for commands)
//       predicate - verb base form
//       patient   - object noun phrase (optional)
//       location  - prepositional phrase e.g. "in the park" (optional)
//       tense     - "present" | "past" | "future"  (default: "present")
//       aspect    - "simple" | "progressive" | "perfect"  (default: "simple")
//       lang      - ISO 639-1 code (default: "en")
//
//   generate_lang(semantic_form_json, lang_code) -> String
//     JSON-based API with explicit language code (overrides any "lang" in JSON).
//
//   generate_frame(frame: SemFrame) -> String
//     High-level SemFrame API.  Language from frame's "lang" field (default "en").
//     Intents: "assert" | "query" | "describe" | "greet".
//
//   generate_frame_lang(frame: SemFrame, lang_code: String) -> String
//     High-level SemFrame API with explicit language code override.

// ── JSON helpers ──────────────────────────────────────────────────────────────

fn sem_get(json: String, key: String) -> String {
    let val: String = json_get(json, key)
    return val
}

// ── Public API: SemFrame ──────────────────────────────────────────────────────

// Generate text from a SemFrame in the language embedded in the frame (default "en").
fn generate_frame(frame: [String]) -> String {
    return sem_realize(frame)
}

// Generate text from a SemFrame in the specified language.
fn generate_frame_lang(frame: [String], lang_code: String) -> String {
    return sem_realize_lang(frame, lang_code)
}

// ── Public API: JSON ──────────────────────────────────────────────────────────

// Build a realizer slot map from JSON fields and an explicit lang code.
fn build_form_from_json(semantic_form_json: String, lang_code: String) -> [String] {
    let intent: String    = sem_get(semantic_form_json, "intent")
    let agent: String     = sem_get(semantic_form_json, "agent")
    let predicate: String = sem_get(semantic_form_json, "predicate")
    let patient: String   = sem_get(semantic_form_json, "patient")
    let location: String  = sem_get(semantic_form_json, "location")
    let tense: String     = sem_get(semantic_form_json, "tense")
    let aspect: String    = sem_get(semantic_form_json, "aspect")

    let form: [String] = native_list_empty()
    let form = native_list_append(form, "intent")
    let form = native_list_append(form, intent)
    let form = native_list_append(form, "agent")
    let form = native_list_append(form, agent)
    let form = native_list_append(form, "predicate")
    let form = native_list_append(form, predicate)
    let form = native_list_append(form, "patient")
    let form = native_list_append(form, patient)
    let form = native_list_append(form, "location")
    let form = native_list_append(form, location)
    let form = native_list_append(form, "tense")
    let form = native_list_append(form, tense)
    let form = native_list_append(form, "aspect")
    let form = native_list_append(form, aspect)
    let form = native_list_append(form, "lang")
    let form = native_list_append(form, lang_code)

    return form
}

// Generate text from a JSON semantic form.  Language defaults to "en" unless
// the JSON contains a "lang" field.
fn generate(semantic_form_json: String) -> String {
    let lang_in_json: String = sem_get(semantic_form_json, "lang")
    let lang_code: String = lang_in_json
    if str_eq(lang_code, "") {
        let lang_code = "en"
    }
    let form: [String] = build_form_from_json(semantic_form_json, lang_code)
    return realize(form)
}

// Generate text from a JSON semantic form in the specified language.
// lang_code overrides any "lang" field present in the JSON.
fn generate_lang(semantic_form_json: String, lang_code: String) -> String {
    let form: [String] = build_form_from_json(semantic_form_json, lang_code)
    return realize(form)
}
