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

el_val_t bm25_tokenize(el_val_t text);
el_val_t bm25_count_term(el_val_t term, el_val_t doc_tokens);
el_val_t bm25_score_doc(el_val_t doc_content, el_val_t query_tokens, el_val_t corpus_size, el_val_t avg_doc_len);
el_val_t bm25_search_json(el_val_t query, el_val_t limit);
el_val_t parse_port(el_val_t bind);
el_val_t ok_json(void);
el_val_t err_json(el_val_t msg);
el_val_t strip_query(el_val_t path);
el_val_t query_param(el_val_t path, el_val_t key);
el_val_t query_int(el_val_t path, el_val_t key, el_val_t default_val);
el_val_t extract_id(el_val_t path, el_val_t prefix);
el_val_t route_stats(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_create_node(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_get_node(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_scan_nodes(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_scan_edges(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_search(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_activate(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_create_edge(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_neighbors(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_strengthen(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_forget(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_decay(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_export(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_reindex(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_load(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_health(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_neuron_session_begin(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_neuron_ctx(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_neuron_memory(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_neuron_knowledge_capture(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_neuron_knowledge_evolve(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_neuron_knowledge_promote(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_neuron_recall(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_neuron_graph(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_neuron_graph_link(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_neuron_list(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_neuron_consolidate(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_neuron_config(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_neuron_state_events(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_neuron_processes(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_events_next(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_events_ack(el_val_t method, el_val_t path, el_val_t body);
el_val_t route_bm25_search(el_val_t method, el_val_t path, el_val_t body);
el_val_t check_auth_ok(el_val_t method, el_val_t body);
el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body);

el_val_t bind_str;
el_val_t port;
el_val_t data_dir;
el_val_t db_path;
el_val_t loaded;

el_val_t bm25_tokenize(el_val_t text) {
  el_val_t t = str_to_lower(text);
  t = str_replace(t, EL_STR("."), EL_STR(" "));
  t = str_replace(t, EL_STR(","), EL_STR(" "));
  t = str_replace(t, EL_STR("!"), EL_STR(" "));
  t = str_replace(t, EL_STR("?"), EL_STR(" "));
  t = str_replace(t, EL_STR("\""), EL_STR(" "));
  t = str_replace(t, EL_STR(":"), EL_STR(" "));
  t = str_replace(t, EL_STR(";"), EL_STR(" "));
  t = str_replace(t, EL_STR("("), EL_STR(" "));
  t = str_replace(t, EL_STR(")"), EL_STR(" "));
  t = str_replace(t, EL_STR("["), EL_STR(" "));
  t = str_replace(t, EL_STR("]"), EL_STR(" "));
  t = str_replace(t, EL_STR("{"), EL_STR(" "));
  t = str_replace(t, EL_STR("}"), EL_STR(" "));
  t = str_replace(t, EL_STR("/"), EL_STR(" "));
  t = str_replace(t, EL_STR("\\"), EL_STR(" "));
  t = str_replace(t, EL_STR("'"), EL_STR(" "));
  t = str_replace(t, EL_STR("-"), EL_STR(" "));
  t = str_replace(t, EL_STR("_"), EL_STR(" "));
  t = str_replace(t, EL_STR("+"), EL_STR(" "));
  return str_trim(t);
  return 0;
}

el_val_t bm25_count_term(el_val_t term, el_val_t doc_tokens) {
  el_val_t padded_term = el_str_concat(el_str_concat(EL_STR(" "), term), EL_STR(" "));
  el_val_t padded_doc = el_str_concat(el_str_concat(EL_STR(" "), doc_tokens), EL_STR(" "));
  return str_count(padded_doc, padded_term);
  return 0;
}

el_val_t bm25_score_doc(el_val_t doc_content, el_val_t query_tokens, el_val_t corpus_size, el_val_t avg_doc_len) {
  el_val_t k1 = el_from_float(1.2);
  el_val_t b = el_from_float(0.75);
  el_val_t delta = el_from_float(1.0);
  el_val_t doc_tokens = bm25_tokenize(doc_content);
  el_val_t doc_wc = str_count_words(doc_tokens);
  if (doc_wc == 0) {
    return EL_STR("0.0");
  }
  el_val_t doc_len = int_to_float(doc_wc);
  el_val_t avg_len = str_to_float(avg_doc_len);
  el_val_t N = int_to_float(corpus_size);
  el_val_t idf_arg = float_add(float_div(float_add(N, el_from_float(1.2)), el_from_float(1.5)), el_from_float(1.0));
  el_val_t idf = math_log(idf_arg);
  el_val_t terms = str_split(query_tokens, EL_STR(" "));
  el_val_t n_terms = len(terms);
  el_val_t score = el_from_float(0.0);
  el_val_t i = 0;
  while (i < n_terms) {
    el_val_t term = get(terms, i);
    el_val_t tlen = str_len(term);
    if (tlen >= 2) {
      el_val_t tf_count = bm25_count_term(term, doc_tokens);
      if (tf_count > 0) {
        el_val_t tf_raw = int_to_float(tf_count);
        el_val_t norm_factor = float_add(float_sub(el_from_float(1.0), b), float_div(float_mul(b, doc_len), avg_len));
        el_val_t numerator = float_mul(tf_raw, float_add(k1, el_from_float(1.0)));
        el_val_t denominator = float_add(tf_raw, float_mul(k1, norm_factor));
        el_val_t tf_comp = float_add(delta, float_div(numerator, denominator));
        score = float_add(score, float_mul(idf, tf_comp));
      }
    }
    i = (i + 1);
  }
  return float_to_str(score);
  return 0;
}

el_val_t bm25_search_json(el_val_t query, el_val_t limit) {
  el_val_t scan_limit = (limit * 10);
  if (scan_limit < 200) {
    scan_limit = 200;
  }
  if (scan_limit > 500) {
    scan_limit = 500;
  }
  el_val_t nodes_json = engram_scan_nodes_json(scan_limit, 0);
  el_val_t n = json_array_len(nodes_json);
  if (n == 0) {
    return EL_STR("[]");
  }
  el_val_t total_words = 0;
  el_val_t i = 0;
  while (i < n) {
    el_val_t node = json_array_get(nodes_json, i);
    el_val_t content = json_get_string(node, EL_STR("content"));
    el_val_t tokens = bm25_tokenize(content);
    el_val_t wc = str_count_words(tokens);
    total_words = (total_words + wc);
    i = (i + 1);
  }
  el_val_t avg_doc_len_f = float_div(int_to_float(total_words), int_to_float(n));
  el_val_t avg_doc_len = ({ el_val_t _if_result_1 = 0; if (float_gt(avg_doc_len_f, el_from_float(0.0))) { _if_result_1 = (float_to_str(avg_doc_len_f)); } else { _if_result_1 = (EL_STR("1.0")); } _if_result_1; });
  el_val_t query_tokens = bm25_tokenize(query);
  if (str_eq(str_trim(query_tokens), EL_STR(""))) {
    return EL_STR("[]");
  }
  el_val_t result_nodes = 0;
  el_val_t result_scores = 0;
  el_val_t result_count = 0;
  el_val_t j = 0;
  while (j < n) {
    el_val_t node = json_array_get(nodes_json, j);
    el_val_t content = json_get_string(node, EL_STR("content"));
    el_val_t sc_str = bm25_score_doc(content, query_tokens, n, avg_doc_len);
    if (float_gt(str_to_float(sc_str), el_from_float(0.0))) {
      result_nodes = list_push(result_nodes, node);
      result_scores = list_push(result_scores, sc_str);
      result_count = (result_count + 1);
    }
    j = (j + 1);
  }
  if (result_count == 0) {
    return EL_STR("[]");
  }
  el_val_t out_limit = ({ el_val_t _if_result_2 = 0; if ((result_count < limit)) { _if_result_2 = (result_count); } else { _if_result_2 = (limit); } _if_result_2; });
  el_val_t k = 0;
  while (k < out_limit) {
    el_val_t max_idx = k;
    el_val_t max_sc_str = get(result_scores, k);
    el_val_t max_sc_f = str_to_float(max_sc_str);
    el_val_t p = (k + 1);
    while (p < result_count) {
      el_val_t sc2_str = get(result_scores, p);
      el_val_t sc2_f = str_to_float(sc2_str);
      if (float_gt(sc2_f, max_sc_f)) {
        max_sc_f = sc2_f;
        max_sc_str = sc2_str;
        max_idx = p;
      }
      p = (p + 1);
    }
    if (max_idx != k) {
      el_val_t tmp_node = get(result_nodes, k);
      el_val_t tmp_sc = get(result_scores, k);
      result_nodes = list_set(result_nodes, k, get(result_nodes, max_idx));
      result_scores = list_set(result_scores, k, get(result_scores, max_idx));
      result_nodes = list_set(result_nodes, max_idx, tmp_node);
      result_scores = list_set(result_scores, max_idx, tmp_sc);
    }
    k = (k + 1);
  }
  el_val_t out = EL_STR("[");
  el_val_t r = 0;
  while (r < out_limit) {
    el_val_t node = get(result_nodes, r);
    el_val_t sc_str = get(result_scores, r);
    el_val_t node_len = str_len(node);
    el_val_t node_body = str_slice(node, 0, (node_len - 1));
    el_val_t entry = el_str_concat(el_str_concat(el_str_concat(node_body, EL_STR(",\"bm25_score\":")), sc_str), EL_STR("}"));
    if (r > 0) {
      out = el_str_concat(out, EL_STR(","));
    }
    out = el_str_concat(out, entry);
    r = (r + 1);
  }
  return el_str_concat(out, EL_STR("]"));
  return 0;
}

el_val_t parse_port(el_val_t bind) {
  el_val_t colon = str_index_of(bind, EL_STR(":"));
  if (colon < 0) {
    return str_to_int(bind);
  }
  el_val_t after = str_slice(bind, (colon + 1), str_len(bind));
  return str_to_int(after);
  return 0;
}

el_val_t ok_json(void) {
  return EL_STR("{\"ok\":true}");
  return 0;
}

el_val_t err_json(el_val_t msg) {
  return el_str_concat(el_str_concat(EL_STR("{\"error\":\""), msg), EL_STR("\"}"));
  return 0;
}

el_val_t strip_query(el_val_t path) {
  el_val_t q = str_index_of(path, EL_STR("?"));
  if (q < 0) {
    return path;
  }
  return str_slice(path, 0, q);
  return 0;
}

el_val_t query_param(el_val_t path, el_val_t key) {
  el_val_t q = str_index_of(path, EL_STR("?"));
  if (q < 0) {
    return EL_STR("");
  }
  el_val_t qs = str_slice(path, (q + 1), str_len(path));
  el_val_t needle = el_str_concat(key, EL_STR("="));
  el_val_t pos = str_index_of(qs, needle);
  if (pos < 0) {
    return EL_STR("");
  }
  el_val_t after = str_slice(qs, (pos + str_len(needle)), str_len(qs));
  el_val_t amp = str_index_of(after, EL_STR("&"));
  if (amp < 0) {
    return after;
  }
  return str_slice(after, 0, amp);
  return 0;
}

el_val_t query_int(el_val_t path, el_val_t key, el_val_t default_val) {
  el_val_t v = query_param(path, key);
  if (str_eq(v, EL_STR(""))) {
    return default_val;
  }
  return str_to_int(v);
  return 0;
}

el_val_t extract_id(el_val_t path, el_val_t prefix) {
  el_val_t clean = strip_query(path);
  if (!str_starts_with(clean, prefix)) {
    return EL_STR("");
  }
  el_val_t after = str_slice(clean, str_len(prefix), str_len(clean));
  el_val_t slash = str_index_of(after, EL_STR("/"));
  if (slash < 0) {
    return after;
  }
  return str_slice(after, 0, slash);
  return 0;
}

el_val_t route_stats(el_val_t method, el_val_t path, el_val_t body) {
  return engram_stats_json();
  return 0;
}

el_val_t route_create_node(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t content = json_get_string(body, EL_STR("content"));
  el_val_t node_type = json_get_string(body, EL_STR("node_type"));
  if (str_eq(node_type, EL_STR(""))) {
    node_type = EL_STR("Memory");
  }
  el_val_t salience = json_get_float(body, EL_STR("salience"));
  if (salience == el_from_float(0.0)) {
    salience = el_from_float(0.5);
  }
  el_val_t id = engram_node(content, node_type, salience);
  el_val_t auto_linked = 0;
  el_val_t clen = str_len(content);
  if (clen >= 20) {
    el_val_t sp1 = str_index_of(content, EL_STR(" "));
    el_val_t w1end = sp1;
    if (sp1 < 0) {
      w1end = clen;
    }
    el_val_t word1 = str_slice(content, 0, w1end);
    el_val_t search_term = EL_STR("");
    if (str_len(word1) >= 5) {
      search_term = word1;
    }
    if (str_eq(search_term, EL_STR(""))) {
      if (sp1 >= 0) {
        el_val_t rest = str_slice(content, (sp1 + 1), clen);
        el_val_t sp2 = str_index_of(rest, EL_STR(" "));
        el_val_t w2end = sp2;
        if (sp2 < 0) {
          w2end = str_len(rest);
        }
        el_val_t word2 = str_slice(rest, 0, w2end);
        if (str_len(word2) >= 5) {
          search_term = word2;
        }
      }
    }
    if (!str_eq(search_term, EL_STR(""))) {
      el_val_t results = engram_search_json(search_term, 10);
      el_val_t n = json_array_len(results);
      el_val_t i = 0;
      while (i < n) {
        if (auto_linked >= 5) {
          i = n;
        }
        if (auto_linked < 5) {
          el_val_t elem = json_array_get(results, i);
          el_val_t rid = json_get_string(elem, EL_STR("id"));
          if (!str_eq(rid, EL_STR(""))) {
            if (!str_eq(rid, id)) {
              engram_connect(id, rid, el_from_float(0.5), EL_STR("related"));
              auto_linked = (auto_linked + 1);
            }
          }
          i = (i + 1);
        }
      }
    }
  }
  return 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("{\"id\":\""), id), EL_STR("\",\"content\":\"")), content), EL_STR("\",\"node_type\":\"")), node_type), EL_STR("\",\"auto_linked\":")), int_to_str(auto_linked)), EL_STR("}"));
  return 0;
}

el_val_t route_get_node(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t id = extract_id(path, EL_STR("/api/nodes/"));
  if (str_eq(id, EL_STR(""))) {
    return err_json(EL_STR("missing id"));
  }
  return engram_get_node_json(id);
  return 0;
}

el_val_t route_scan_nodes(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t limit = query_int(path, EL_STR("limit"), 50);
  el_val_t offset = query_int(path, EL_STR("offset"), 0);
  el_val_t nt = query_param(path, EL_STR("node_type"));
  if (str_eq(nt, EL_STR(""))) {
    return engram_scan_nodes_json(limit, offset);
  }
  return engram_scan_nodes_by_type_json(nt, limit, offset);
  return 0;
}

el_val_t route_scan_edges(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t dir = env(EL_STR("ENGRAM_DATA_DIR"));
  if (str_eq(dir, EL_STR(""))) {
    dir = EL_STR("/tmp/engram");
  }
  el_val_t snap_path = el_str_concat(dir, EL_STR("/snapshot.json"));
  engram_save(snap_path);
  el_val_t snap = fs_read(snap_path);
  if (str_eq(snap, EL_STR(""))) {
    return EL_STR("[]");
  }
  el_val_t edges = json_get_raw(snap, EL_STR("edges"));
  if (str_eq(edges, EL_STR(""))) {
    return EL_STR("[]");
  }
  return edges;
  return 0;
}

el_val_t route_search(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t q = EL_STR("");
  if (str_eq(method, EL_STR("GET"))) {
    q = query_param(path, EL_STR("q"));
  } else {
    q = json_get_string(body, EL_STR("query"));
  }
  el_val_t limit = query_int(path, EL_STR("limit"), 20);
  if (limit == 0) {
    limit = json_get_int(body, EL_STR("limit"));
  }
  if (limit == 0) {
    limit = 20;
  }
  return bm25_search_json(q, limit);
  return 0;
}

el_val_t route_activate(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t q = EL_STR("");
  el_val_t depth = 3;
  if (str_eq(method, EL_STR("GET"))) {
    q = query_param(path, EL_STR("q"));
    depth = query_int(path, EL_STR("depth"), 3);
  } else {
    q = json_get_string(body, EL_STR("query"));
    el_val_t bd = json_get_int(body, EL_STR("depth"));
    if (bd > 0) {
      depth = bd;
    }
  }
  el_val_t top = bm25_search_json(q, 10);
  el_val_t nb = json_array_len(top);
  el_val_t bi = 0;
  while (bi < nb) {
    el_val_t node = json_array_get(top, bi);
    el_val_t nid = json_get_string(node, EL_STR("id"));
    if (!str_eq(nid, EL_STR(""))) {
      engram_strengthen(nid);
    }
    bi = (bi + 1);
  }
  return el_str_concat(el_str_concat(EL_STR("{\"results\":"), engram_activate_json(q, depth)), EL_STR("}"));
  return 0;
}

el_val_t route_create_edge(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t from_id = json_get_string(body, EL_STR("from_id"));
  el_val_t to_id = json_get_string(body, EL_STR("to_id"));
  el_val_t relation = json_get_string(body, EL_STR("relation"));
  if (str_eq(relation, EL_STR(""))) {
    relation = EL_STR("associates");
  }
  el_val_t weight = json_get_float(body, EL_STR("weight"));
  if (weight == el_from_float(0.0)) {
    weight = el_from_float(0.5);
  }
  engram_connect(from_id, to_id, weight, relation);
  return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"from_id\":\""), from_id), EL_STR("\",\"to_id\":\"")), to_id), EL_STR("\",\"relation\":\"")), relation), EL_STR("\"}"));
  return 0;
}

el_val_t route_neighbors(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t id = extract_id(path, EL_STR("/api/neighbors/"));
  if (str_eq(id, EL_STR(""))) {
    return err_json(EL_STR("missing id"));
  }
  el_val_t depth = query_int(path, EL_STR("depth"), 1);
  return engram_neighbors_json(id, depth, EL_STR("both"));
  return 0;
}

el_val_t route_strengthen(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t id = json_get_string(body, EL_STR("node_id"));
  if (str_eq(id, EL_STR(""))) {
    return err_json(EL_STR("missing node_id"));
  }
  engram_strengthen(id);
  return ok_json();
  return 0;
}

el_val_t route_forget(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t id = extract_id(path, EL_STR("/api/nodes/"));
  if (str_eq(id, EL_STR(""))) {
    return err_json(EL_STR("missing id"));
  }
  engram_forget(id);
  return ok_json();
  return 0;
}

el_val_t route_decay(el_val_t method, el_val_t path, el_val_t body) {
  return engram_apply_decay_json();
  return 0;
}

el_val_t route_export(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t dir = env(EL_STR("ENGRAM_DATA_DIR"));
  if (str_eq(dir, EL_STR(""))) {
    dir = EL_STR("/tmp/engram");
  }
  el_val_t db_path = el_str_concat(dir, EL_STR("/engram.db"));
  engram_write_binary_el(db_path);
  el_val_t p = json_get_string(body, EL_STR("path"));
  if (str_eq(p, EL_STR(""))) {
    p = el_str_concat(dir, EL_STR("/snapshot.json"));
  }
  engram_save(p);
  return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"binary\":\""), db_path), EL_STR("\",\"json\":\"")), p), EL_STR("\"}"));
  return 0;
}

el_val_t route_reindex(el_val_t method, el_val_t path, el_val_t body) {
  return engram_reindex_json();
  return 0;
}

el_val_t route_load(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t dir = env(EL_STR("ENGRAM_DATA_DIR"));
  if (str_eq(dir, EL_STR(""))) {
    dir = EL_STR("/tmp/engram");
  }
  el_val_t db_path = el_str_concat(dir, EL_STR("/engram.db"));
  el_val_t ok = engram_load_binary_el(db_path);
  if (!ok) {
    el_val_t p = json_get_string(body, EL_STR("path"));
    if (str_eq(p, EL_STR(""))) {
      p = el_str_concat(dir, EL_STR("/snapshot.json"));
    }
    engram_load(p);
  }
  return ok_json();
  return 0;
}

el_val_t route_health(el_val_t method, el_val_t path, el_val_t body) {
  return EL_STR("{\"status\":\"ok\",\"engine\":\"engram-runtime-native\"}");
  return 0;
}

el_val_t route_neuron_session_begin(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t results = engram_activate_json(EL_STR("memory knowledge context"), 2);
  el_val_t nc = engram_node_count();
  el_val_t ec = engram_edge_count();
  return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"nodes\":"), results), EL_STR(",\"node_count\":")), int_to_str(nc)), EL_STR(",\"edge_count\":")), int_to_str(ec)), EL_STR("}"));
  return 0;
}

el_val_t route_neuron_ctx(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t results = engram_activate_json(EL_STR("architecture decision memory"), 2);
  el_val_t n = json_array_len(results);
  el_val_t limit = ({ el_val_t _if_result_3 = 0; if ((n > 10)) { _if_result_3 = (10); } else { _if_result_3 = (n); } _if_result_3; });
  el_val_t ctx = EL_STR("Recent working memory:\n");
  el_val_t i = 0;
  el_val_t ctx_body = EL_STR("");
  while (i < limit) {
    el_val_t elem = json_array_get(results, i);
    el_val_t label = json_get_string(elem, EL_STR("label"));
    el_val_t content = json_get_string(elem, EL_STR("content"));
    el_val_t clen = str_len(content);
    el_val_t snippet = ({ el_val_t _if_result_4 = 0; if ((clen > 200)) { _if_result_4 = (str_slice(content, 0, 200)); } else { _if_result_4 = (content); } _if_result_4; });
    ctx_body = el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(ctx_body, EL_STR("- [")), label), EL_STR("]: ")), snippet), EL_STR("\n"));
    i = (i + 1);
  }
  el_val_t full_ctx = el_str_concat(ctx, ctx_body);
  return el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"context\":\""), str_replace(str_replace(str_replace(full_ctx, EL_STR("\\"), EL_STR("\\\\")), EL_STR("\""), EL_STR("\\\"")), EL_STR("\n"), EL_STR("\\n"))), EL_STR("\"}"));
  return 0;
}

el_val_t route_neuron_memory(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t content = json_get_string(body, EL_STR("content"));
  if (str_eq(content, EL_STR(""))) {
    return EL_STR("{\"error\":\"content is required\"}");
  }
  el_val_t node_type = json_get_string(body, EL_STR("node_type"));
  if (str_eq(node_type, EL_STR(""))) {
    node_type = EL_STR("Memory");
  }
  el_val_t label = json_get_string(body, EL_STR("label"));
  el_val_t importance = json_get_string(body, EL_STR("importance"));
  el_val_t project = json_get_string(body, EL_STR("project"));
  el_val_t tags_raw = json_get_string(body, EL_STR("tags"));
  el_val_t tier = EL_STR("Episodic");
  if (str_eq(importance, EL_STR("critical"))) {
    tier = EL_STR("Procedural");
  }
  if (str_eq(importance, EL_STR("high"))) {
    tier = EL_STR("Semantic");
  }
  if (str_eq(importance, EL_STR("normal"))) {
    tier = EL_STR("Episodic");
  }
  if (str_eq(importance, EL_STR("low"))) {
    tier = EL_STR("Working");
  }
  el_val_t explicit_tier = json_get_string(body, EL_STR("tier"));
  if (!str_eq(explicit_tier, EL_STR(""))) {
    tier = explicit_tier;
  }
  el_val_t tags_str = tags_raw;
  if (!str_eq(project, EL_STR(""))) {
    if (str_eq(tags_str, EL_STR(""))) {
      tags_str = el_str_concat(EL_STR("project:"), project);
    }
    if (!str_eq(tags_str, EL_STR(""))) {
      tags_str = el_str_concat(el_str_concat(tags_str, EL_STR(" project:")), project);
    }
  }
  el_val_t id = engram_node_full(content, node_type, label, el_from_float(0.5), el_from_float(0.5), el_from_float(1.0), tier, tags_str);
  el_val_t dir = env(EL_STR("ENGRAM_DATA_DIR"));
  if (str_eq(dir, EL_STR(""))) {
    dir = EL_STR("/tmp/engram");
  }
  el_val_t db_path = el_str_concat(dir, EL_STR("/engram.db"));
  engram_write_binary_el(db_path);
  return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"id\":\""), id), EL_STR("\",\"content\":\"")), str_replace(str_replace(content, EL_STR("\\"), EL_STR("\\\\")), EL_STR("\""), EL_STR("\\\""))), EL_STR("\"}"));
  return 0;
}

el_val_t route_neuron_knowledge_capture(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t content = json_get_string(body, EL_STR("content"));
  if (str_eq(content, EL_STR(""))) {
    return EL_STR("{\"error\":\"content is required\"}");
  }
  el_val_t title = json_get_string(body, EL_STR("title"));
  el_val_t category = json_get_string(body, EL_STR("category"));
  el_val_t tags_raw = json_get_string(body, EL_STR("tags"));
  el_val_t project = json_get_string(body, EL_STR("project"));
  el_val_t tier_raw = json_get_string(body, EL_STR("tier"));
  el_val_t tier = EL_STR("Episodic");
  if (str_eq(tier_raw, EL_STR("lesson"))) {
    tier = EL_STR("Semantic");
  }
  if (str_eq(tier_raw, EL_STR("canonical"))) {
    tier = EL_STR("Procedural");
  }
  if (str_eq(tier_raw, EL_STR("note"))) {
    tier = EL_STR("Episodic");
  }
  el_val_t tags_str = tags_raw;
  if (!str_eq(category, EL_STR(""))) {
    if (str_eq(tags_str, EL_STR(""))) {
      tags_str = el_str_concat(EL_STR("category:"), category);
    }
    if (!str_eq(tags_str, EL_STR(""))) {
      tags_str = el_str_concat(el_str_concat(tags_str, EL_STR(" category:")), category);
    }
  }
  if (!str_eq(project, EL_STR(""))) {
    if (str_eq(tags_str, EL_STR(""))) {
      tags_str = el_str_concat(EL_STR("project:"), project);
    }
    if (!str_eq(tags_str, EL_STR(""))) {
      tags_str = el_str_concat(el_str_concat(tags_str, EL_STR(" project:")), project);
    }
  }
  el_val_t id = engram_node_full(content, EL_STR("Knowledge"), title, el_from_float(0.7), el_from_float(0.7), el_from_float(1.0), tier, tags_str);
  el_val_t dir = env(EL_STR("ENGRAM_DATA_DIR"));
  if (str_eq(dir, EL_STR(""))) {
    dir = EL_STR("/tmp/engram");
  }
  el_val_t db_path = el_str_concat(dir, EL_STR("/engram.db"));
  engram_write_binary_el(db_path);
  return el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"id\":\""), id), EL_STR("\"}"));
  return 0;
}

el_val_t route_neuron_knowledge_evolve(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t content = json_get_string(body, EL_STR("content"));
  el_val_t prior_id = json_get_string(body, EL_STR("id"));
  if (str_eq(content, EL_STR(""))) {
    return EL_STR("{\"ok\":true}");
  }
  el_val_t id = engram_node_full(content, EL_STR("Knowledge"), EL_STR(""), el_from_float(0.7), el_from_float(0.7), el_from_float(1.0), EL_STR("Semantic"), EL_STR("evolved"));
  if (!str_eq(prior_id, EL_STR("")) && !str_eq(id, EL_STR(""))) {
    engram_connect(id, prior_id, el_from_float(1.0), EL_STR("supersedes"));
  }
  el_val_t dir = env(EL_STR("ENGRAM_DATA_DIR"));
  if (str_eq(dir, EL_STR(""))) {
    dir = EL_STR("/tmp/engram");
  }
  engram_write_binary_el(el_str_concat(dir, EL_STR("/engram.db")));
  return el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"id\":\""), id), EL_STR("\"}"));
  return 0;
}

el_val_t route_neuron_knowledge_promote(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t id = json_get_string(body, EL_STR("id"));
  if (str_eq(id, EL_STR(""))) {
    return EL_STR("{\"ok\":true}");
  }
  el_val_t node_json = engram_get_node_json(id);
  if (str_eq(node_json, EL_STR(""))) {
    return err_json(EL_STR("node not found"));
  }
  if (str_eq(node_json, EL_STR("null"))) {
    return err_json(EL_STR("node not found"));
  }
  el_val_t content = json_get_string(node_json, EL_STR("content"));
  if (str_eq(content, EL_STR(""))) {
    return err_json(EL_STR("node has no content"));
  }
  el_val_t label = json_get_string(node_json, EL_STR("label"));
  el_val_t tags = json_get_string(node_json, EL_STR("tags"));
  el_val_t current_tier = json_get_string(node_json, EL_STR("tier"));
  el_val_t tier_raw = json_get_string(body, EL_STR("tier"));
  el_val_t new_tier = EL_STR("");
  if (str_eq(tier_raw, EL_STR("lesson"))) {
    new_tier = EL_STR("Semantic");
  }
  if (str_eq(tier_raw, EL_STR("canonical"))) {
    new_tier = EL_STR("Procedural");
  }
  if (str_eq(tier_raw, EL_STR("note"))) {
    new_tier = EL_STR("Episodic");
  }
  if (str_eq(new_tier, EL_STR(""))) {
    if (str_eq(current_tier, EL_STR("Working"))) {
      new_tier = EL_STR("Episodic");
    }
    if (str_eq(current_tier, EL_STR("Episodic"))) {
      new_tier = EL_STR("Semantic");
    }
    if (str_eq(current_tier, EL_STR("Semantic"))) {
      new_tier = EL_STR("Procedural");
    }
    if (str_eq(current_tier, EL_STR("Procedural"))) {
      new_tier = EL_STR("Procedural");
    }
  }
  if (str_eq(new_tier, EL_STR(""))) {
    new_tier = EL_STR("Semantic");
  }
  el_val_t new_id = engram_node_full(content, EL_STR("Knowledge"), label, el_from_float(0.7), el_from_float(0.8), el_from_float(1.0), new_tier, tags);
  if (!str_eq(new_id, EL_STR(""))) {
    engram_connect(new_id, id, el_from_float(1.0), EL_STR("supersedes"));
  }
  el_val_t dir = env(EL_STR("ENGRAM_DATA_DIR"));
  if (str_eq(dir, EL_STR(""))) {
    dir = EL_STR("/tmp/engram");
  }
  engram_write_binary_el(el_str_concat(dir, EL_STR("/engram.db")));
  return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"id\":\""), new_id), EL_STR("\",\"promoted_from\":\"")), id), EL_STR("\",\"tier\":\"")), new_tier), EL_STR("\"}"));
  return 0;
}

el_val_t route_neuron_recall(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t query = json_get_string(body, EL_STR("query"));
  el_val_t chain = json_get_string(body, EL_STR("chain_name"));
  el_val_t limit = json_get_int(body, EL_STR("limit"));
  if (limit == 0) {
    limit = 20;
  }
  el_val_t q = ({ el_val_t _if_result_5 = 0; if (str_eq(query, EL_STR(""))) { _if_result_5 = (chain); } else { _if_result_5 = (query); } _if_result_5; });
  if (str_eq(q, EL_STR(""))) {
    return engram_scan_nodes_json(limit, 0);
  }
  return bm25_search_json(q, limit);
  return 0;
}

el_val_t route_neuron_graph(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t id = query_param(path, EL_STR("id"));
  if (str_eq(id, EL_STR(""))) {
    return EL_STR("{\"error\":\"id is required\"}");
  }
  el_val_t node_json = engram_get_node_json(id);
  return el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"node\":"), node_json), EL_STR(",\"neighbors\":[]}"));
  return 0;
}

el_val_t route_neuron_graph_link(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t from_id = json_get_string(body, EL_STR("from_id"));
  el_val_t to_id = json_get_string(body, EL_STR("to_id"));
  if (str_eq(from_id, EL_STR("")) || str_eq(to_id, EL_STR(""))) {
    return EL_STR("{\"error\":\"from_id and to_id are required\"}");
  }
  el_val_t relation = json_get_string(body, EL_STR("relation"));
  if (str_eq(relation, EL_STR(""))) {
    relation = EL_STR("related");
  }
  el_val_t weight = json_get_float(body, EL_STR("weight"));
  if (weight == el_from_float(0.0)) {
    weight = el_from_float(0.5);
  }
  engram_connect(from_id, to_id, weight, relation);
  return el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"from_id\":\""), from_id), EL_STR("\",\"to_id\":\"")), to_id), EL_STR("\",\"relation\":\"")), relation), EL_STR("\"}"));
  return 0;
}

el_val_t route_neuron_list(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t clean = strip_query(path);
  el_val_t prefix = EL_STR("/api/neuron/list/");
  el_val_t node_type = str_slice(clean, str_len(prefix), str_len(clean));
  el_val_t limit = query_int(path, EL_STR("limit"), 50);
  if (str_eq(node_type, EL_STR(""))) {
    return EL_STR("[]");
  }
  return engram_scan_nodes_by_type_json(node_type, limit, 0);
  return 0;
}

el_val_t route_neuron_consolidate(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t dir = env(EL_STR("ENGRAM_DATA_DIR"));
  if (str_eq(dir, EL_STR(""))) {
    dir = EL_STR("/tmp/engram");
  }
  el_val_t db_path = el_str_concat(dir, EL_STR("/engram.db"));
  engram_write_binary_el(db_path);
  el_val_t nc = engram_node_count();
  el_val_t ec = engram_edge_count();
  return el_str_concat(el_str_concat(el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"node_count\":"), int_to_str(nc)), EL_STR(",\"edge_count\":")), int_to_str(ec)), EL_STR("}"));
  return 0;
}

el_val_t route_neuron_config(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t key = query_param(path, EL_STR("key"));
  return el_str_concat(el_str_concat(EL_STR("{\"key\":\""), key), EL_STR("\",\"value\":\"\"}"));
  return 0;
}

el_val_t route_neuron_state_events(el_val_t method, el_val_t path, el_val_t body) {
  if (str_eq(method, EL_STR("GET"))) {
    el_val_t limit_str = query_param(path, EL_STR("limit"));
    el_val_t limit = ({ el_val_t _if_result_6 = 0; if (str_eq(limit_str, EL_STR(""))) { _if_result_6 = (50); } else { _if_result_6 = (str_to_int(limit_str)); } _if_result_6; });
    el_val_t offset_str = query_param(path, EL_STR("offset"));
    el_val_t offset = ({ el_val_t _if_result_7 = 0; if (str_eq(offset_str, EL_STR(""))) { _if_result_7 = (0); } else { _if_result_7 = (str_to_int(offset_str)); } _if_result_7; });
    return engram_scan_nodes_by_type_json(EL_STR("InternalStateEvent"), limit, offset);
  }
  el_val_t content = json_get_string(body, EL_STR("content"));
  if (str_eq(content, EL_STR(""))) {
    content = body;
  }
  el_val_t event_label = json_get_string(content, EL_STR("event"));
  el_val_t label = ({ el_val_t _if_result_8 = 0; if (str_eq(event_label, EL_STR(""))) { _if_result_8 = (EL_STR("state-event")); } else { _if_result_8 = (event_label); } _if_result_8; });
  el_val_t id = engram_node_full(content, EL_STR("InternalStateEvent"), label, el_from_float(0.3), el_from_float(0.3), el_from_float(1.0), EL_STR("Working"), EL_STR("internal-state"));
  return el_str_concat(el_str_concat(EL_STR("{\"ok\":true,\"id\":\""), id), EL_STR("\"}"));
  return 0;
}

el_val_t route_neuron_processes(el_val_t method, el_val_t path, el_val_t body) {
  return EL_STR("{\"ok\":true,\"processes\":[]}");
  return 0;
}

el_val_t route_events_next(el_val_t method, el_val_t path, el_val_t body) {
  return EL_STR("{\"ok\":true,\"event\":null}");
  return 0;
}

el_val_t route_events_ack(el_val_t method, el_val_t path, el_val_t body) {
  return EL_STR("{\"ok\":true}");
  return 0;
}

el_val_t route_bm25_search(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t q = EL_STR("");
  if (str_eq(method, EL_STR("GET"))) {
    q = query_param(path, EL_STR("q"));
  } else {
    q = json_get_string(body, EL_STR("query"));
  }
  if (str_eq(q, EL_STR(""))) {
    return EL_STR("{\"error\":\"query is required\"}");
  }
  el_val_t limit = query_int(path, EL_STR("limit"), 20);
  if (limit == 0) {
    limit = json_get_int(body, EL_STR("limit"));
  }
  if (limit == 0) {
    limit = 20;
  }
  return bm25_search_json(q, limit);
  return 0;
}

el_val_t check_auth_ok(el_val_t method, el_val_t body) {
  el_val_t key = env(EL_STR("ENGRAM_API_KEY"));
  if (str_eq(key, EL_STR(""))) {
    return 1;
  }
  if (str_eq(method, EL_STR("GET"))) {
    return 1;
  }
  el_val_t provided = json_get_string(body, EL_STR("_auth"));
  if (str_eq(provided, key)) {
    return 1;
  }
  return 0;
  return 0;
}

el_val_t handle_request(el_val_t method, el_val_t path, el_val_t body) {
  el_val_t clean = strip_query(path);
  if (str_eq(method, EL_STR("GET"))) {
    if (str_eq(clean, EL_STR("/health")) || str_eq(clean, EL_STR("/"))) {
      return route_health(method, path, body);
    }
  }
  if (str_starts_with(clean, EL_STR("/api/neuron/")) || str_starts_with(clean, EL_STR("/events/"))) {
    if (str_eq(clean, EL_STR("/api/neuron/session/begin"))) {
      return route_neuron_session_begin(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/ctx"))) {
      return route_neuron_ctx(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/memory"))) {
      return route_neuron_memory(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/knowledge/capture"))) {
      return route_neuron_knowledge_capture(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/knowledge/evolve"))) {
      return route_neuron_knowledge_evolve(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/knowledge/promote"))) {
      return route_neuron_knowledge_promote(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/recall"))) {
      return route_neuron_recall(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/graph/link"))) {
      return route_neuron_graph_link(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/graph"))) {
      return route_neuron_graph(method, path, body);
    }
    if (str_starts_with(clean, EL_STR("/api/neuron/list/"))) {
      return route_neuron_list(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/consolidate"))) {
      return route_neuron_consolidate(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/config"))) {
      return route_neuron_config(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/state-events"))) {
      return route_neuron_state_events(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/processes/define"))) {
      return route_neuron_processes(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/processes"))) {
      return route_neuron_processes(method, path, body);
    }
    if (str_eq(clean, EL_STR("/events/next"))) {
      return route_events_next(method, path, body);
    }
    if (str_eq(clean, EL_STR("/events/ack"))) {
      return route_events_ack(method, path, body);
    }
    return err_json(EL_STR("not found"));
  }
  if (!check_auth_ok(method, body)) {
    return err_json(EL_STR("unauthorized"));
  }
  if (str_eq(method, EL_STR("GET")) && (str_eq(clean, EL_STR("/api/stats")) || str_eq(clean, EL_STR("/stats")))) {
    return route_stats(method, path, body);
  }
  if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/nodes")) || str_eq(clean, EL_STR("/nodes")))) {
    return route_create_node(method, path, body);
  }
  if (str_eq(method, EL_STR("GET")) && (((str_eq(clean, EL_STR("/api/nodes")) || str_eq(clean, EL_STR("/nodes"))) || str_eq(clean, EL_STR("/nodes/list"))) || str_eq(clean, EL_STR("/api/nodes/list")))) {
    return route_scan_nodes(method, path, body);
  }
  if (str_eq(method, EL_STR("GET")) && (str_eq(clean, EL_STR("/api/edges")) || str_eq(clean, EL_STR("/edges")))) {
    return route_scan_edges(method, path, body);
  }
  if (str_eq(method, EL_STR("GET")) && str_starts_with(clean, EL_STR("/api/nodes/"))) {
    return route_get_node(method, path, body);
  }
  if (str_eq(method, EL_STR("DELETE")) && str_starts_with(clean, EL_STR("/api/nodes/"))) {
    return route_forget(method, path, body);
  }
  if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/edges")) || str_eq(clean, EL_STR("/edges")))) {
    return route_create_edge(method, path, body);
  }
  if (str_eq(method, EL_STR("GET")) && str_starts_with(clean, EL_STR("/api/neighbors/"))) {
    return route_neighbors(method, path, body);
  }
  if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/activate")) || str_eq(clean, EL_STR("/activate")))) {
    return route_activate(method, path, body);
  }
  if (str_eq(method, EL_STR("GET")) && str_starts_with(clean, EL_STR("/api/activate"))) {
    return route_activate(method, path, body);
  }
  if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/search")) || str_eq(clean, EL_STR("/search")))) {
    return route_search(method, path, body);
  }
  if (str_eq(method, EL_STR("GET")) && str_starts_with(clean, EL_STR("/api/search"))) {
    return route_search(method, path, body);
  }
  if (str_eq(clean, EL_STR("/api/bm25/search"))) {
    return route_bm25_search(method, path, body);
  }
  if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/strengthen")) || str_eq(clean, EL_STR("/strengthen")))) {
    return route_strengthen(method, path, body);
  }
  if (str_eq(method, EL_STR("POST")) && ((str_eq(clean, EL_STR("/api/decay")) || str_eq(clean, EL_STR("/api/maintenance"))) || str_eq(clean, EL_STR("/decay")))) {
    return route_decay(method, path, body);
  }
  if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/export")) || str_eq(clean, EL_STR("/export")))) {
    return route_export(method, path, body);
  }
  if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/save")) || str_eq(clean, EL_STR("/save")))) {
    return route_export(method, path, body);
  }
  if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/load")) || str_eq(clean, EL_STR("/load")))) {
    return route_load(method, path, body);
  }
  if (str_eq(method, EL_STR("POST")) && (str_eq(clean, EL_STR("/api/reindex")) || str_eq(clean, EL_STR("/reindex")))) {
    return route_reindex(method, path, body);
  }
  if (str_starts_with(clean, EL_STR("/api/neuron/"))) {
    if (str_eq(clean, EL_STR("/api/neuron/session/begin"))) {
      return route_neuron_session_begin(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/ctx"))) {
      return route_neuron_ctx(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/memory"))) {
      return route_neuron_memory(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/knowledge/capture"))) {
      return route_neuron_knowledge_capture(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/knowledge/evolve"))) {
      return route_neuron_knowledge_evolve(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/knowledge/promote"))) {
      return route_neuron_knowledge_promote(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/recall"))) {
      return route_neuron_recall(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/graph/link"))) {
      return route_neuron_graph_link(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/graph"))) {
      return route_neuron_graph(method, path, body);
    }
    if (str_starts_with(clean, EL_STR("/api/neuron/list/"))) {
      return route_neuron_list(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/consolidate"))) {
      return route_neuron_consolidate(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/config"))) {
      return route_neuron_config(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/state-events"))) {
      return route_neuron_state_events(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/processes/define"))) {
      return route_neuron_processes(method, path, body);
    }
    if (str_eq(clean, EL_STR("/api/neuron/processes"))) {
      return route_neuron_processes(method, path, body);
    }
  }
  if (str_eq(clean, EL_STR("/events/next"))) {
    return route_events_next(method, path, body);
  }
  if (str_eq(clean, EL_STR("/events/ack"))) {
    return route_events_ack(method, path, body);
  }
  return el_str_concat(el_str_concat(EL_STR("{\"error\":\"not found\",\"path\":\""), clean), EL_STR("\"}"));
  return 0;
}

int main(int _argc, char** _argv) {
  el_runtime_init_args(_argc, _argv);
  bind_str = env(EL_STR("ENGRAM_BIND"));
  if (str_eq(bind_str, EL_STR(""))) {
    bind_str = EL_STR(":8742");
  }
  port = parse_port(bind_str);
  data_dir = env(EL_STR("ENGRAM_DATA_DIR"));
  if (str_eq(data_dir, EL_STR(""))) {
    data_dir = EL_STR("/tmp/engram");
  }
  db_path = el_str_concat(data_dir, EL_STR("/engram.db"));
  loaded = engram_load_binary_el(db_path);
  if (!loaded) {
    engram_load_dir(data_dir);
    if (engram_node_count() == 0) {
      el_val_t snapshot_path = el_str_concat(data_dir, EL_STR("/snapshot.json"));
      engram_load(snapshot_path);
    }
    if (engram_node_count() > 0) {
      engram_write_binary_el(db_path);
      println(EL_STR("[engram] migrated legacy data to binary format"));
    }
  }
  println(EL_STR("[engram] runtime-native graph engine (ML-KEM-1024 encrypted)"));
  println(el_str_concat(EL_STR("[engram] data_dir="), data_dir));
  println(el_str_concat(EL_STR("[engram] node_count="), int_to_str(engram_node_count())));
  println(el_str_concat(EL_STR("[engram] edge_count="), int_to_str(engram_edge_count())));
  println(el_str_concat(EL_STR("[engram] listening on "), int_to_str(port)));
  http_set_handler(EL_STR("handle_request"));
  http_serve(port, EL_STR("handle_request"));
  return 0;
}

