#include <stdint.h>
#include <stdlib.h>
#include "el_runtime.h"

el_val_t sem_get(el_val_t json, el_val_t key);
el_val_t generate_frame(el_val_t frame);
el_val_t generate_frame_lang(el_val_t frame, el_val_t lang_code);
el_val_t build_form_from_json(el_val_t semantic_form_json, el_val_t lang_code);
el_val_t generate(el_val_t semantic_form_json);
el_val_t generate_lang(el_val_t semantic_form_json, el_val_t lang_code);
el_val_t elp_extract_topic(el_val_t msg);
el_val_t elp_detect_predicate(el_val_t msg);
el_val_t elp_parse(el_val_t msg);
el_val_t handle_elp_chat(el_val_t body);

el_val_t elp_extract_topic(el_val_t msg) {
  el_val_t m1 = ({ el_val_t _if_result_1 = 0; if (str_starts_with(msg, EL_STR("What is "))) { _if_result_1 = (str_slice(msg, 8, str_len(msg))); } else { _if_result_1 = (msg); } _if_result_1; });
  el_val_t m2 = ({ el_val_t _if_result_2 = 0; if (str_starts_with(m1, EL_STR("What are "))) { _if_result_2 = (str_slice(m1, 9, str_len(m1))); } else { _if_result_2 = (m1); } _if_result_2; });
  el_val_t m3 = ({ el_val_t _if_result_3 = 0; if (str_starts_with(m2, EL_STR("Tell me about "))) { _if_result_3 = (str_slice(m2, 14, str_len(m2))); } else { _if_result_3 = (m2); } _if_result_3; });
  el_val_t m4 = ({ el_val_t _if_result_4 = 0; if (str_starts_with(m3, EL_STR("Who is "))) { _if_result_4 = (str_slice(m3, 7, str_len(m3))); } else { _if_result_4 = (m3); } _if_result_4; });
  el_val_t m5 = ({ el_val_t _if_result_5 = 0; if (str_starts_with(m4, EL_STR("Who are "))) { _if_result_5 = (str_slice(m4, 8, str_len(m4))); } else { _if_result_5 = (m4); } _if_result_5; });
  el_val_t m6 = ({ el_val_t _if_result_6 = 0; if (str_starts_with(m5, EL_STR("How do you "))) { _if_result_6 = (str_slice(m5, 11, str_len(m5))); } else { _if_result_6 = (m5); } _if_result_6; });
  el_val_t m7 = ({ el_val_t _if_result_7 = 0; if (str_starts_with(m6, EL_STR("Why "))) { _if_result_7 = (str_slice(m6, 4, str_len(m6))); } else { _if_result_7 = (m6); } _if_result_7; });
  el_val_t m8 = ({ el_val_t _if_result_8 = 0; if (str_starts_with(m7, EL_STR("Explain "))) { _if_result_8 = (str_slice(m7, 8, str_len(m7))); } else { _if_result_8 = (m7); } _if_result_8; });
  el_val_t last = (str_len(m8) - 1);
  el_val_t trail = str_slice(m8, last, str_len(m8));
  el_val_t clean = ({ el_val_t _if_result_9 = 0; if (((str_eq(trail, EL_STR("?")) || str_eq(trail, EL_STR("."))) || str_eq(trail, EL_STR("!")))) { _if_result_9 = (str_slice(m8, 0, last)); } else { _if_result_9 = (m8); } _if_result_9; });
  return clean;
  return 0;
}

el_val_t elp_detect_predicate(el_val_t msg) {
  if ((str_starts_with(msg, EL_STR("What is ")) || str_starts_with(msg, EL_STR("What are "))) || str_starts_with(msg, EL_STR("Tell me about "))) {
    return EL_STR("tell");
  }
  if (str_starts_with(msg, EL_STR("Who is ")) || str_starts_with(msg, EL_STR("Who are "))) {
    return EL_STR("identify");
  }
  if (str_starts_with(msg, EL_STR("Why ")) || str_starts_with(msg, EL_STR("Explain "))) {
    return EL_STR("explain");
  }
  if (str_starts_with(msg, EL_STR("How do you feel")) || str_starts_with(msg, EL_STR("Do you "))) {
    return EL_STR("express");
  }
  if (str_starts_with(msg, EL_STR("Remember ")) || str_starts_with(msg, EL_STR("Store "))) {
    return EL_STR("store");
  }
  return EL_STR("tell");
  return 0;
}

el_val_t elp_parse(el_val_t msg) {
  el_val_t predicate = elp_detect_predicate(msg);
  el_val_t topic = elp_extract_topic(msg);
  el_val_t safe_topic = str_replace(topic, EL_STR("\""), EL_STR("'"));
  return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"predicate\":\""), predicate), EL_STR("\",\"args\":[\"")), safe_topic), EL_STR("\"],\"modifiers\":[],\"context\":{}}"));
  return 0;
}

el_val_t handle_elp_chat(el_val_t body) {
  el_val_t message = json_get(body, EL_STR("message"));
  if (str_eq(message, EL_STR(""))) {
    return EL_STR("{\"error\":\"message required\",\"response\":\"\"}");
  }
  el_val_t frame = elp_parse(message);
  el_val_t predicate = elp_detect_predicate(message);
  el_val_t topic = elp_extract_topic(message);
  el_val_t from_topic = engram_activate_json(topic, 10);
  el_val_t topic_ok = (!str_eq(from_topic, EL_STR("")) && !str_eq(from_topic, EL_STR("[]")));
  el_val_t candidates = ({ el_val_t _if_result_10 = 0; if (topic_ok) { _if_result_10 = (from_topic); } else { el_val_t from_msg = engram_activate_json(message, 10); el_val_t msg_ok = (!str_eq(from_msg, EL_STR("")) && !str_eq(from_msg, EL_STR("[]"))); _if_result_10 = (({ el_val_t _if_result_11 = 0; if (msg_ok) { _if_result_11 = (from_msg); } else { _if_result_11 = (engram_scan_nodes_json(5, 0)); } _if_result_11; })); } _if_result_10; });
  el_val_t total = json_array_len(candidates);
  el_val_t fi = 0;
  el_val_t kept_count = 0;
  el_val_t kept_json = EL_STR("");
  while (fi < total) {
    el_val_t n = json_array_get(candidates, fi);
    el_val_t sal_str = json_get(n, EL_STR("salience"));
    el_val_t imp_str = json_get(n, EL_STR("importance"));
    el_val_t sal_ok = ((!str_eq(sal_str, EL_STR("0")) && !str_eq(sal_str, EL_STR("0.0"))) && !str_eq(sal_str, EL_STR("")));
    el_val_t imp_ok = ((!str_eq(imp_str, EL_STR("0")) && !str_eq(imp_str, EL_STR("0.0"))) && !str_eq(imp_str, EL_STR("")));
    el_val_t keep_it = ((sal_ok || imp_ok) || (kept_count == 0));
    if (keep_it && (kept_count < 3)) {
      el_val_t sep = ({ el_val_t _if_result_12 = 0; if (str_eq(kept_json, EL_STR(""))) { _if_result_12 = (EL_STR("")); } else { _if_result_12 = (EL_STR(",")); } _if_result_12; });
      kept_json = el_str_concat(el_str_concat(kept_json, sep), n);
      kept_count = (kept_count + 1);
    }
    fi = (fi + 1);
  }
  el_val_t frame_nodes = ({ el_val_t _if_result_13 = 0; if (str_eq(kept_json, EL_STR(""))) { _if_result_13 = (EL_STR("[]")); } else { _if_result_13 = (el_str_concat(el_str_concat(EL_STR("["), kept_json), EL_STR("]"))); } _if_result_13; });
  el_val_t fn_total = json_array_len(frame_nodes);
  el_val_t fn_i = 0;
  el_val_t topic_lower = str_to_lower(topic);
  el_val_t found_node = EL_STR("");
  while (fn_i < fn_total) {
    el_val_t candidate = json_array_get(frame_nodes, fn_i);
    el_val_t cand_content = json_get(candidate, EL_STR("content"));
    el_val_t cand_lower = str_to_lower(cand_content);
    el_val_t matches = str_contains(cand_lower, topic_lower);
    if (matches && str_eq(found_node, EL_STR(""))) {
      found_node = candidate;
    }
    fn_i = (fn_i + 1);
  }
  el_val_t top_node = ({ el_val_t _if_result_14 = 0; if (str_eq(found_node, EL_STR(""))) { _if_result_14 = (json_array_get(frame_nodes, 0)); } else { _if_result_14 = (found_node); } _if_result_14; });
  el_val_t top_raw = json_get(top_node, EL_STR("content"));
  el_val_t patient_raw = ({ el_val_t _if_result_15 = 0; if (str_eq(top_raw, EL_STR(""))) { _if_result_15 = (topic); } else { _if_result_15 = (({ el_val_t _if_result_16 = 0; if ((str_len(top_raw) > 200)) { _if_result_16 = (str_slice(top_raw, 0, 200)); } else { _if_result_16 = (top_raw); } _if_result_16; })); } _if_result_15; });
  el_val_t patient_safe = str_replace(str_replace(patient_raw, EL_STR("\""), EL_STR("'")), EL_STR("\n"), EL_STR(" "));
  el_val_t intent_val = ({ el_val_t _if_result_17 = 0; if (str_eq(predicate, EL_STR("store"))) { _if_result_17 = (EL_STR("command")); } else { _if_result_17 = (EL_STR("assert")); } _if_result_17; });
  el_val_t gen_form = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"intent\":\""), intent_val), EL_STR("\"")), EL_STR(",\"agent\":\"I\"")), EL_STR(",\"predicate\":\"")), predicate), EL_STR("\"")), EL_STR(",\"patient\":\"")), patient_safe), EL_STR("\"")), EL_STR(",\"tense\":\"present\",\"aspect\":\"simple\",\"lang\":\"en\"}"));
  el_val_t realized = generate(gen_form);
  el_val_t response = ({ el_val_t _if_result_18 = 0; if (str_eq(realized, EL_STR(""))) { _if_result_18 = (({ el_val_t _if_result_19 = 0; if (str_eq(patient_safe, EL_STR(""))) { _if_result_19 = (EL_STR("Nothing in the engram matched that query.")); } else { _if_result_19 = (patient_safe); } _if_result_19; })); } else { _if_result_18 = (realized); } _if_result_18; });
  el_val_t safe_resp = str_replace(str_replace(response, EL_STR("\""), EL_STR("'")), EL_STR("\r"), EL_STR(""));
  return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"response\":\""), safe_resp), EL_STR("\",\"model\":\"elp-native\",\"frame\":")), frame), EL_STR(",\"nodes\":")), frame_nodes), EL_STR("}"));
  return 0;
}

