view mrjunejune/main.c @ 279:b3b547563ec7

Add Google connector service and agent wiki Implement the C/Seobeo Google Drive and Gmail connector with encrypted OAuth storage, Zenbu authentication, browser testing, AI tool discovery, chunked HTTP decoding, and Bazel coverage. Consolidate repository guidance into progressive wiki documentation and enforce arena-first allocation for new first-party C code. Co-authored-by: Copilot <[email protected]> Copilot-Session: 84c338fd-0939-4bb3-b7f3-1062eb213e5d
author MrJuneJune <me@mrjunejune.com>
date Mon, 17 Aug 2026 22:22:36 -0700
parents e02e2036ef84
children
line wrap: on
line source

#include "seobeo/seobeo.h"
#include "markdown_converter/markdown_to_html.h"
#include "s3/s3_uploader.h"
#include "deita/deita.h"
#include "mrjunejune/latex_renderer.h"
#include "mrjunejune/conversation_api.h"
#include "mrjunejune/auth_api.h"
#include "mrjunejune/admin_api.h"
#include "mrjunejune/template_renderer.h"
#include "auth/auth_crypto.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <time.h>
#include <sys/stat.h>
#include <stdarg.h>
#include <stdatomic.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <openssl/crypto.h>

// UUID + /tmp/ + format (max 4)
#define TMP_FILE_LENGTH 47
#define UUID_LEN 37

volatile sig_atomic_t stop_server = 0;
static _Atomic uint32 counter = 0;
static _Atomic boolean g_latex_rendering = FALSE;
static Seobeo_Worker_Pool *g_media_worker_pool = NULL;

// Media processing context owned by a background worker.
typedef struct {
  int64    media_id;
  char     s3_key_original[512];
  char     s3_key_processed[512];
  char     content_type[128];
  char     access_token[256];
  char     db_path[256];
  S3_Config s3_config;
} Media_Processing_Context;

typedef struct {
  char *input_path;
  char *output_path;
  int result;
} File_Converter_Config;

// Server configuration (loaded from .config)
static char g_upload_auth_token[256] = {0};
static char g_s3_region[64] = "us-west-2";
static char g_s3_bucket[128] = "mrjunejune";
static char g_s3_cloudfront_url[256] = {0};
static char g_db_path[256] = "mrjunejune/data/mrjunejune.db";
static int  g_s3_url_expires = 3600;
static S3_Config g_s3_config = {0};
static Deita_Connection *g_db_connection = NULL;
/* S3 credentials — never logged; zero after use in init. */
static char g_s3_access_key[128] = {0};
static char g_s3_secret_key[128] = {0};

/* Auth configuration */
static char    g_auth_cookie_secret[AUTH_CRYPTO_COOKIE_SECRET_MAX_BYTES * 2 + 1] = {0};
static char    g_auth_bootstrap_username[64] = {0};
static char    g_auth_bootstrap_password_hash[AUTH_CRYPTO_PASSWORD_HASH_ENCODED_SIZE] = {0};
static char    g_auth_trusted_proxy[AUTH_CRYPTO_IP_MAX_BYTES] = {0};
static int64   g_auth_session_idle_ttl = AUTH_API_SESSION_IDLE_TTL_DEFAULT;
static int64   g_auth_session_abs_ttl  = AUTH_API_SESSION_ABS_TTL_DEFAULT;
static int64   g_auth_guest_ttl        = AUTH_API_GUEST_TTL_DEFAULT;
static boolean g_auth_dev_insecure     = FALSE;
static char    g_server_host[128]      = {0};   /* SERVER_HOST; empty → 0.0.0.0 */

/* Guest inference / quota configuration */
#define G_GUEST_DAILY_TURNS_DEFAULT         10
#define G_GUEST_DAILY_OUTPUT_TOKENS_DEFAULT 20000
#define G_GUEST_REQUEST_OUTPUT_TOKENS_MIN   1
#define G_GUEST_DAILY_TURNS_MIN             1
#define G_GUEST_DAILY_TURNS_MAX             10000
#define G_GUEST_DAILY_OUTPUT_TOKENS_MIN     1
#define G_GUEST_DAILY_OUTPUT_TOKENS_MAX     1000000
#define G_GUEST_REQUEST_OUTPUT_TOKENS_DEFAULT 2048
static boolean g_guest_inference_enabled     = FALSE;
static int64   g_guest_daily_turns           = G_GUEST_DAILY_TURNS_DEFAULT;
static int64   g_guest_daily_output_tokens   = G_GUEST_DAILY_OUTPUT_TOKENS_DEFAULT;
static int64   g_guest_request_output_tokens = G_GUEST_REQUEST_OUTPUT_TOKENS_DEFAULT;

/*
 * Strict full-string integer parse: returns FALSE if value is empty,
 * has trailing non-digit characters, or overflows a long.
 */
static boolean config__parse_int64_strict(const char *value, int64 *out)
{
  if (!value || value[0] == '\0')
    return FALSE;
  char *end = NULL;
  long v = strtol(value, &end, 10);
  if (end == value || *end != '\0')
    return FALSE;
  *out = (int64)v;
  return TRUE;
}

/*
 * Decode a lowercase or uppercase hex string into raw bytes.
 * Returns the number of decoded bytes, or 0 on any error.
 * hex_len must be even; each pair of hex chars produces one byte.
 */
static size_t config__hex_decode(const char *hex, uint8 *out, size_t out_capacity)
{
  if (!hex || !out) return 0;
  size_t hex_len = strlen(hex);
  if (hex_len == 0 || hex_len % 2 != 0) return 0;
  size_t byte_count = hex_len / 2;
  if (byte_count > out_capacity) return 0;
  for (size_t i = 0; i < byte_count; i++)
  {
    int h, l;
    char hi = hex[i * 2];
    char lo = hex[i * 2 + 1];
    if      (hi >= '0' && hi <= '9') h = hi - '0';
    else if (hi >= 'a' && hi <= 'f') h = hi - 'a' + 10;
    else if (hi >= 'A' && hi <= 'F') h = hi - 'A' + 10;
    else return 0;
    if      (lo >= '0' && lo <= '9') l = lo - '0';
    else if (lo >= 'a' && lo <= 'f') l = lo - 'a' + 10;
    else if (lo >= 'A' && lo <= 'F') l = lo - 'A' + 10;
    else return 0;
    out[i] = (uint8)((h << 4) | l);
  }
  return byte_count;
}

static void load_config(const char *config_path)
{
  boolean config_loaded = FALSE;
  FILE *f = fopen(config_path, "r");
  char workspace_config_path[1024] = {0};
  if (!f)
  {
    const char *workspace = getenv("BUILD_WORKSPACE_DIRECTORY");
    if (workspace && workspace[0] != '\0')
    {
      int written = snprintf(
          workspace_config_path,
          sizeof(workspace_config_path),
          "%s/%s",
          workspace,
          config_path);
      if (written > 0 && (size_t)written < sizeof(workspace_config_path))
        f = fopen(workspace_config_path, "r");
    }
  }
  if (!f)
  {
    printf("[CONFIG] Warning: Could not open %s, using defaults\n", config_path);
  }
  else
  {
    config_loaded = TRUE;
    char line[512];
    while (fgets(line, sizeof(line), f))
    {
      // Skip comments and empty lines
      if (line[0] == '#' || line[0] == '\n' || line[0] == '\r') continue;

      char *eq = strchr(line, '=');
      if (!eq) continue;

      *eq = '\0';
      char *key = line;
      char *value = eq + 1;

      // Trim newline from value
      size_t vlen = strlen(value);
      while (vlen > 0 && (value[vlen-1] == '\n' || value[vlen-1] == '\r'))
        value[--vlen] = '\0';

      if (strcmp(key, "UPLOAD_AUTH_TOKEN") == 0)
      {
        strncpy(g_upload_auth_token, value, sizeof(g_upload_auth_token) - 1);
      }
    else if (strcmp(key, "S3_REGION") == 0)
    {
      strncpy(g_s3_region, value, sizeof(g_s3_region) - 1);
    }
    else if (strcmp(key, "S3_BUCKET") == 0)
    {
      strncpy(g_s3_bucket, value, sizeof(g_s3_bucket) - 1);
    }
    else if (strcmp(key, "S3_URL_EXPIRES") == 0)
    {
      int64 v;
      if (!config__parse_int64_strict(value, &v) || v <= 0)
      {
        fprintf(stderr, "[CONFIG] ERROR: S3_URL_EXPIRES must be a positive integer\n");
        exit(1);
      }
      g_s3_url_expires = (int)v;
    }
    else if (strcmp(key, "S3_CLOUDFRONT_URL") == 0)
    {
      strncpy(g_s3_cloudfront_url, value, sizeof(g_s3_cloudfront_url) - 1);
    }
    else if (strcmp(key, "DB_PATH") == 0)
    {
      strncpy(g_db_path, value, sizeof(g_db_path) - 1);
    }
    else if (strcmp(key, "AWS_MRJUNEJUNE_ACCESS_KEY") == 0)
    {
      strncpy(g_s3_access_key, value, sizeof(g_s3_access_key) - 1);
    }
    else if (strcmp(key, "AWS_MRJUNEJUNE_SECRET_ACCESS_KEY") == 0)
    {
      strncpy(g_s3_secret_key, value, sizeof(g_s3_secret_key) - 1);
    }
    else if (strcmp(key, "AUTH_COOKIE_SECRET") == 0)
    {
      /* Never log this value */
      strncpy(g_auth_cookie_secret, value, sizeof(g_auth_cookie_secret) - 1);
    }
    else if (strcmp(key, "AUTH_BOOTSTRAP_USERNAME") == 0)
    {
      strncpy(g_auth_bootstrap_username, value,
              sizeof(g_auth_bootstrap_username) - 1);
    }
    else if (strcmp(key, "AUTH_BOOTSTRAP_PASSWORD_HASH") == 0)
    {
      strncpy(g_auth_bootstrap_password_hash, value,
              sizeof(g_auth_bootstrap_password_hash) - 1);
    }
    else if (strcmp(key, "AUTH_TRUSTED_PROXY") == 0)
    {
      strncpy(g_auth_trusted_proxy, value, sizeof(g_auth_trusted_proxy) - 1);
    }
    else if (strcmp(key, "AUTH_SESSION_IDLE_TTL") == 0)
    {
      int64 v;
      if (!config__parse_int64_strict(value, &v) || v <= 0)
      {
        fprintf(stderr, "[CONFIG] ERROR: AUTH_SESSION_IDLE_TTL must be a positive integer\n");
        exit(1);
      }
      g_auth_session_idle_ttl = v;
    }
    else if (strcmp(key, "AUTH_SESSION_ABS_TTL") == 0)
    {
      int64 v;
      if (!config__parse_int64_strict(value, &v) || v <= 0)
      {
        fprintf(stderr, "[CONFIG] ERROR: AUTH_SESSION_ABS_TTL must be a positive integer\n");
        exit(1);
      }
      g_auth_session_abs_ttl = v;
    }
    else if (strcmp(key, "AUTH_GUEST_TTL") == 0)
    {
      int64 v;
      if (!config__parse_int64_strict(value, &v) || v <= 0)
      {
        fprintf(stderr, "[CONFIG] ERROR: AUTH_GUEST_TTL must be a positive integer\n");
        exit(1);
      }
      g_auth_guest_ttl = v;
    }
      else if (strcmp(key, "AUTH_DEV_INSECURE_COOKIE") == 0)
      {
        g_auth_dev_insecure =
            (strcmp(value, "1") == 0 || strcmp(value, "true") == 0);
      }
      else if (strcmp(key, "SERVER_HOST") == 0)
      {
        strncpy(g_server_host, value, sizeof(g_server_host) - 1);
      }
      else if (strcmp(key, "MRJUNEJUNE_ALLOW_GUEST_INFERENCE") == 0)
      {
        if (strcmp(value, "1") == 0 || strcasecmp(value, "true") == 0)
          g_guest_inference_enabled = TRUE;
        else if (strcmp(value, "0") == 0 || strcasecmp(value, "false") == 0)
          g_guest_inference_enabled = FALSE;
        else
        {
          fprintf(
              stderr,
              "[CONFIG] ERROR: MRJUNEJUNE_ALLOW_GUEST_INFERENCE must be true or false\n");
          exit(1);
        }
      }
      else if (strcmp(key, "AUTH_GUEST_DAILY_TURNS") == 0)
      {
        int64 v;
        if (!config__parse_int64_strict(value, &v) ||
            v < G_GUEST_DAILY_TURNS_MIN || v > G_GUEST_DAILY_TURNS_MAX)
        {
          printf("[CONFIG] ERROR: AUTH_GUEST_DAILY_TURNS must be %d..%d\n",
                 G_GUEST_DAILY_TURNS_MIN, G_GUEST_DAILY_TURNS_MAX);
          exit(1);
        }
        g_guest_daily_turns = v;
      }
      else if (strcmp(key, "AUTH_GUEST_DAILY_OUTPUT_TOKENS") == 0)
      {
        int64 v;
        if (!config__parse_int64_strict(value, &v) ||
            v < G_GUEST_DAILY_OUTPUT_TOKENS_MIN ||
            v > G_GUEST_DAILY_OUTPUT_TOKENS_MAX)
        {
          printf("[CONFIG] ERROR: AUTH_GUEST_DAILY_OUTPUT_TOKENS must be %d..%d\n",
                 G_GUEST_DAILY_OUTPUT_TOKENS_MIN, G_GUEST_DAILY_OUTPUT_TOKENS_MAX);
          exit(1);
        }
        g_guest_daily_output_tokens = v;
      }
      else if (strcmp(key, "AUTH_GUEST_REQUEST_OUTPUT_TOKENS") == 0)
      {
        int64 v;
        if (!config__parse_int64_strict(value, &v) ||
            v < G_GUEST_REQUEST_OUTPUT_TOKENS_MIN)
        {
          printf("[CONFIG] ERROR: AUTH_GUEST_REQUEST_OUTPUT_TOKENS must be >= %d\n",
                 G_GUEST_REQUEST_OUTPUT_TOKENS_MIN);
          exit(1);
        }
        g_guest_request_output_tokens = v;
      }
    }
    fclose(f);
  }

  printf("[CONFIG] Loaded: token=%s..., region=%s, bucket=%s, expires=%d, cloudfront=%s, db=%s\n",
         g_upload_auth_token[0] ? "***" : "(empty)",
         g_s3_region, g_s3_bucket, g_s3_url_expires,
         g_s3_cloudfront_url[0] ? g_s3_cloudfront_url : "(none)",
         g_db_path);
  printf("[CONFIG] Auth: secret=%s, bootstrap_user=%s, trusted_proxy=%s\n",
         g_auth_cookie_secret[0] ? "(set)" : "(not set)",
         g_auth_bootstrap_username[0] ? g_auth_bootstrap_username : "(none)",
         g_auth_trusted_proxy[0] ? "(set)" : "(not set)");

  const char *database_path_override = getenv("MRJUNEJUNE_DB_PATH");
  const char *test_tmpdir = getenv("TEST_TMPDIR");
  if (database_path_override && database_path_override[0] != '\0')
  {
    strncpy(g_db_path, database_path_override, sizeof(g_db_path) - 1);
  }
  else if (test_tmpdir && test_tmpdir[0] != '\0')
  {
    snprintf(g_db_path, sizeof(g_db_path), "%s/mrjunejune.db", test_tmpdir);
  }

  /* Environment configuration is a compatibility/testing fallback only when
   * no config file is present. Dynamic supervisor wiring is read separately. */
  if (!config_loaded)
  {
    const char *env;

    /* S3 / server config env overrides */
    if ((env = getenv("UPLOAD_AUTH_TOKEN")) && env[0] != '\0')
      strncpy(g_upload_auth_token, env, sizeof(g_upload_auth_token) - 1);
    if ((env = getenv("S3_REGION")) && env[0] != '\0')
      strncpy(g_s3_region, env, sizeof(g_s3_region) - 1);
    if ((env = getenv("S3_BUCKET")) && env[0] != '\0')
      strncpy(g_s3_bucket, env, sizeof(g_s3_bucket) - 1);
    if ((env = getenv("S3_CLOUDFRONT_URL")) && env[0] != '\0')
      strncpy(g_s3_cloudfront_url, env, sizeof(g_s3_cloudfront_url) - 1);
    if ((env = getenv("S3_URL_EXPIRES")) && env[0] != '\0')
    {
      int64 v;
      if (!config__parse_int64_strict(env, &v) || v <= 0)
      {
        fprintf(stderr, "[CONFIG] ERROR: S3_URL_EXPIRES must be a positive integer\n");
        exit(1);
      }
      g_s3_url_expires = (int)v;
    }
    if ((env = getenv("AWS_MRJUNEJUNE_ACCESS_KEY")) && env[0] != '\0')
      strncpy(g_s3_access_key, env, sizeof(g_s3_access_key) - 1);
    if ((env = getenv("AWS_MRJUNEJUNE_SECRET_ACCESS_KEY")) && env[0] != '\0')
      strncpy(g_s3_secret_key, env, sizeof(g_s3_secret_key) - 1);

    /* Auth env overrides */
    if ((env = getenv("AUTH_COOKIE_SECRET")) && env[0] != '\0')
      strncpy(g_auth_cookie_secret, env, sizeof(g_auth_cookie_secret) - 1);
    if ((env = getenv("AUTH_BOOTSTRAP_USERNAME")) && env[0] != '\0')
      strncpy(g_auth_bootstrap_username, env,
              sizeof(g_auth_bootstrap_username) - 1);
    if ((env = getenv("AUTH_BOOTSTRAP_PASSWORD_HASH")) && env[0] != '\0')
      strncpy(g_auth_bootstrap_password_hash, env,
              sizeof(g_auth_bootstrap_password_hash) - 1);
    if ((env = getenv("AUTH_TRUSTED_PROXY")) && env[0] != '\0')
      strncpy(g_auth_trusted_proxy, env, sizeof(g_auth_trusted_proxy) - 1);
    if ((env = getenv("AUTH_SESSION_IDLE_TTL")) && env[0] != '\0')
    {
      int64 v;
      if (!config__parse_int64_strict(env, &v) || v <= 0)
      {
        fprintf(stderr, "[CONFIG] ERROR: AUTH_SESSION_IDLE_TTL must be a positive integer\n");
        exit(1);
      }
      g_auth_session_idle_ttl = v;
    }
    if ((env = getenv("AUTH_SESSION_ABS_TTL")) && env[0] != '\0')
    {
      int64 v;
      if (!config__parse_int64_strict(env, &v) || v <= 0)
      {
        fprintf(stderr, "[CONFIG] ERROR: AUTH_SESSION_ABS_TTL must be a positive integer\n");
        exit(1);
      }
      g_auth_session_abs_ttl = v;
    }
    if ((env = getenv("AUTH_GUEST_TTL")) && env[0] != '\0')
    {
      int64 v;
      if (!config__parse_int64_strict(env, &v) || v <= 0)
      {
        fprintf(stderr, "[CONFIG] ERROR: AUTH_GUEST_TTL must be a positive integer\n");
        exit(1);
      }
      g_auth_guest_ttl = v;
    }
    if ((env = getenv("AUTH_DEV_INSECURE_COOKIE")) && env[0] != '\0')
      g_auth_dev_insecure =
          (strcmp(env, "1") == 0 || strcmp(env, "true") == 0);
    if ((env = getenv("SERVER_HOST")) && env[0] != '\0')
      strncpy(g_server_host, env, sizeof(g_server_host) - 1);

    /* Guest inference enable: runtime-only, boolean parsed strictly. */
    if ((env = getenv("MRJUNEJUNE_ALLOW_GUEST_INFERENCE")) && env[0] != '\0')
      g_guest_inference_enabled =
          (strcmp(env, "1") == 0 || strcasecmp(env, "true") == 0);
    else if ((env = getenv("MRJUNEJUNE_ALLOW_ANONYMOUS_INFERENCE")) && env[0] != '\0')
      g_guest_inference_enabled =
          (strcmp(env, "1") == 0 || strcasecmp(env, "true") == 0);

    /* Guest quota env overrides: strict full-string integer, fail on malformed. */
    if ((env = getenv("AUTH_GUEST_DAILY_TURNS")) && env[0] != '\0')
    {
      int64 v;
      if (!config__parse_int64_strict(env, &v) ||
          v < G_GUEST_DAILY_TURNS_MIN || v > G_GUEST_DAILY_TURNS_MAX)
      {
        fprintf(stderr,
                "[CONFIG] ERROR: AUTH_GUEST_DAILY_TURNS must be %d..%d\n",
                G_GUEST_DAILY_TURNS_MIN, G_GUEST_DAILY_TURNS_MAX);
        exit(1);
      }
      g_guest_daily_turns = v;
    }
    if ((env = getenv("AUTH_GUEST_DAILY_OUTPUT_TOKENS")) && env[0] != '\0')
    {
      int64 v;
      if (!config__parse_int64_strict(env, &v) ||
          v < G_GUEST_DAILY_OUTPUT_TOKENS_MIN ||
          v > G_GUEST_DAILY_OUTPUT_TOKENS_MAX)
      {
        fprintf(stderr,
                "[CONFIG] ERROR: AUTH_GUEST_DAILY_OUTPUT_TOKENS must be %d..%d\n",
                G_GUEST_DAILY_OUTPUT_TOKENS_MIN, G_GUEST_DAILY_OUTPUT_TOKENS_MAX);
        exit(1);
      }
      g_guest_daily_output_tokens = v;
    }
    if ((env = getenv("AUTH_GUEST_REQUEST_OUTPUT_TOKENS")) && env[0] != '\0')
    {
      int64 v;
      if (!config__parse_int64_strict(env, &v) ||
          v < G_GUEST_REQUEST_OUTPUT_TOKENS_MIN)
      {
        fprintf(stderr,
                "[CONFIG] ERROR: AUTH_GUEST_REQUEST_OUTPUT_TOKENS must be >= %d\n",
                G_GUEST_REQUEST_OUTPUT_TOKENS_MIN);
        exit(1);
      }
      g_guest_request_output_tokens = v;
    }
  }
}

static void init_database(void)
{
  // Create data directory if needed
  char *last_slash = strrchr(g_db_path, '/');
  if (last_slash)
  {
    char dir_path[256];
    size_t dir_len = last_slash - g_db_path;
    strncpy(dir_path, g_db_path, dir_len);
    dir_path[dir_len] = '\0';
    mkdir(dir_path, 0755);
  }

  g_db_connection = Deita_Connection_Create(DEITA_DATABASE_TYPE_SQLITE3, g_db_path);
  if (!g_db_connection || !Deita_Connection_Is_Open(g_db_connection))
  {
    printf("[DB] ERROR: Failed to open database at %s\n", g_db_path);
    return;
  }

  // Create editor_content table
  const char *create_table =
    "CREATE TABLE IF NOT EXISTS editor_content ("
    "  id INTEGER PRIMARY KEY AUTOINCREMENT,"
    "  access_token TEXT NOT NULL,"
    "  doc_id TEXT NOT NULL,"
    "  content TEXT,"
    "  created_at INTEGER DEFAULT (strftime('%s', 'now')),"
    "  updated_at INTEGER DEFAULT (strftime('%s', 'now')),"
    "  UNIQUE(access_token, doc_id)"
    ")";

  int32 result = Deita_Query_Execute_Update(g_db_connection, create_table);
  if (result < 0)
  {
    printf("[DB] ERROR: Failed to create editor_content table\n");
  }

  // Create media_uploads table
  const char *create_media_uploads =
    "CREATE TABLE IF NOT EXISTS media_uploads ("
    "  id INTEGER PRIMARY KEY AUTOINCREMENT,"
    "  access_token TEXT NOT NULL,"
    "  original_filename TEXT NOT NULL,"
    "  content_type TEXT NOT NULL,"
    "  s3_key_original TEXT NOT NULL,"
    "  s3_key_processed TEXT,"
    "  file_size INTEGER,"
    "  status TEXT NOT NULL DEFAULT 'pending',"
    "  error_message TEXT,"
    "  created_at INTEGER DEFAULT (strftime('%s', 'now')),"
    "  updated_at INTEGER DEFAULT (strftime('%s', 'now'))"
    ")";

  result = Deita_Query_Execute_Update(g_db_connection, create_media_uploads);
  if (result < 0)
  {
    printf("[DB] ERROR: Failed to create media_uploads table\n");
  }

  // Create indices for media_uploads
  const char *create_status_idx =
    "CREATE INDEX IF NOT EXISTS idx_media_uploads_status ON media_uploads(status)";
  result = Deita_Query_Execute_Update(g_db_connection, create_status_idx);
  if (result < 0)
  {
    printf("[DB] ERROR: Failed to create status index\n");
  }

  const char *create_token_status_idx =
    "CREATE INDEX IF NOT EXISTS idx_media_uploads_token_status "
    "ON media_uploads(access_token, status)";
  result = Deita_Query_Execute_Update(g_db_connection, create_token_status_idx);
  if (result < 0)
  {
    printf("[DB] ERROR: Failed to create token_status index\n");
  }
  else
  {
    printf("[DB] Initialized: %s\n", g_db_path);
  }
}

void handle_sigint(int sig)
{
  (void)sig;
  stop_server = 1;
  Seobeo_Web_Server_Stop();
}

static Seobeo_Request_Entry *html_render_error(Dowa_Arena *arena, const char *msg)
{
  Seobeo_Request_Entry *resp = NULL;
  Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
  Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain; charset=utf-8", arena);
  Dowa_HashMap_Push_Arena(resp, "body", (char *)msg, arena);
  return resp;
}

#define HTML_PAGE_CAP (128 * 1024)

Seobeo_Request_Entry* GetHomePage(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;
  char *final_body = Dowa_Arena_Allocate(arena, HTML_PAGE_CAP);
  if (!final_body || !Mjj_Template_Render_File(final_body, HTML_PAGE_CAP, "/index.html", arena))
    return html_render_error(arena, "Internal Server Error");
  Dowa_HashMap_Push_Arena(resp, "body", final_body, arena);
  return resp;
}

Seobeo_Request_Entry* GetResume(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;
  char *final_body = Dowa_Arena_Allocate(arena, HTML_PAGE_CAP);
  if (!final_body || !Mjj_Template_Render_File(final_body, HTML_PAGE_CAP, "/resume/index.html", arena))
    return html_render_error(arena, "Internal Server Error");
  Dowa_HashMap_Push_Arena(resp, "body", final_body, arena);
  return resp;
}

Seobeo_Request_Entry* GetTools(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;
  char *final_body = Dowa_Arena_Allocate(arena, HTML_PAGE_CAP);
  if (!final_body || !Mjj_Template_Render_File(final_body, HTML_PAGE_CAP, "/tools/index.html", arena))
    return html_render_error(arena, "Internal Server Error");
  Dowa_HashMap_Push_Arena(resp, "body", final_body, arena);
  return resp;
}


Seobeo_Request_Entry* GetMDToHTML(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;
  char *final_body = Dowa_Arena_Allocate(arena, HTML_PAGE_CAP);
  if (!final_body || !Mjj_Template_Render_File(final_body, HTML_PAGE_CAP, "/tools/markdown_to_html/index.html", arena))
    return html_render_error(arena, "Internal Server Error");
  Dowa_HashMap_Push_Arena(resp, "body", final_body, arena);
  return resp;
}

Seobeo_Request_Entry* GetFileConverter(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;
  char *final_body = Dowa_Arena_Allocate(arena, HTML_PAGE_CAP);
  if (!final_body || !Mjj_Template_Render_File(final_body, HTML_PAGE_CAP, "/tools/file_converter/index.html", arena))
    return html_render_error(arena, "Internal Server Error");
  Dowa_HashMap_Push_Arena(resp, "body", final_body, arena);
  return resp;
}

Seobeo_Request_Entry* GetHlsPlayer(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;
  char *final_body = Dowa_Arena_Allocate(arena, HTML_PAGE_CAP);
  if (!final_body || !Mjj_Template_Render_File(final_body, HTML_PAGE_CAP, "/tools/hls_player/index.html", arena))
    return html_render_error(arena, "Internal Server Error");
  Dowa_HashMap_Push_Arena(resp, "body", final_body, arena);
  return resp;
}

Seobeo_Request_Entry* GetLatexEditor(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;
  char *final_body = Dowa_Arena_Allocate(arena, HTML_PAGE_CAP);
  if (!final_body || !Mjj_Template_Render_File(final_body, HTML_PAGE_CAP, "/tools/latex_editor/index.html", arena))
    return html_render_error(arena, "Internal Server Error");
  Dowa_HashMap_Push_Arena(resp, "body", final_body, arena);
  return resp;
}


static Seobeo_Request_Entry *LatexErrorResponse(
    Dowa_Arena *arena,
    int status,
    const char *message)
{
  Seobeo_Request_Entry *resp = NULL;
  char *status_value = Dowa_Arena_Allocate(arena, 16);
  snprintf(status_value, 16, "%d", status);
  char *body = Dowa_Arena_Allocate(arena, strlen(message) + 1);
  strcpy(body, message);
  Dowa_HashMap_Push_Arena(resp, "status", status_value, arena);
  Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain; charset=utf-8", arena);
  Dowa_HashMap_Push_Arena(resp, "cache-control", "no-store", arena);
  Dowa_HashMap_Push_Arena(resp, "body", body, arena);
  return resp;
}

Seobeo_Request_Entry *RenderLatexPdf(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  void *body_kv = Dowa_HashMap_Get_Ptr(req, "Body");
  void *length_kv = Dowa_HashMap_Get_Ptr(req, "Content-Length");
  if (!body_kv || !length_kv)
    return LatexErrorResponse(arena, 400, "LaTeX source and Content-Length are required.");

  const char *length_value = ((Seobeo_Request_Entry *)length_kv)->value;
  char *length_end = NULL;
  errno = 0;
  unsigned long long parsed_length = strtoull(length_value, &length_end, 10);
  if (errno != 0 ||
      length_end == length_value ||
      *length_end != '\0' ||
      parsed_length == 0)
    return LatexErrorResponse(arena, 400, "Content-Length is invalid.");
  if (parsed_length > LATEX_SOURCE_MAX_BYTES)
    return LatexErrorResponse(arena, 413, "LaTeX source exceeds the 64 KiB limit.");

  boolean expected = FALSE;
  if (!atomic_compare_exchange_strong(
          &g_latex_rendering,
          &expected,
          TRUE))
    return LatexErrorResponse(arena, 429, "The LaTeX compiler is busy. Try again shortly.");

  Latex_Render_Result render = Latex_Render(
      (const uint8 *)((Seobeo_Request_Entry *)body_kv)->value,
      (size_t)parsed_length);
  atomic_store(&g_latex_rendering, FALSE);
  if (render.status != LATEX_RENDER_OK)
  {
    int status = 500;
    if (render.status == LATEX_RENDER_INVALID_INPUT)
      status = 400;
    else if (render.status == LATEX_RENDER_COMPILE_ERROR)
      status = 422;
    else if (render.status == LATEX_RENDER_TIMEOUT)
      status = 504;
    else if (render.status == LATEX_RENDER_COMPILER_UNAVAILABLE)
      status = 503;

    const char *diagnostics = render.diagnostics
        ? render.diagnostics
        : "LaTeX rendering failed.";
    char *body = Dowa_Arena_Allocate(arena, strlen(diagnostics) + 1);
    strcpy(body, diagnostics);
    Latex_Render_Result_Destroy(&render);
    return LatexErrorResponse(arena, status, body);
  }

  char *pdf = Dowa_Arena_Allocate(arena, render.pdf_size + 1);
  if (!pdf)
  {
    Latex_Render_Result_Destroy(&render);
    return LatexErrorResponse(arena, 500, "The generated PDF is too large to return.");
  }
  memcpy(pdf, render.pdf_data, render.pdf_size);
  pdf[render.pdf_size] = '\0';
  char *content_length = Dowa_Arena_Allocate(arena, 32);
  snprintf(content_length, 32, "%zu", render.pdf_size);
  Latex_Render_Result_Destroy(&render);

  Seobeo_Request_Entry *resp = NULL;
  Dowa_HashMap_Push_Arena(resp, "status", "200", arena);
  Dowa_HashMap_Push_Arena(resp, "content-type", "application/pdf", arena);
  Dowa_HashMap_Push_Arena(resp, "content-length", content_length, arena);
  Dowa_HashMap_Push_Arena(resp, "content-disposition", "inline; filename=\"document.pdf\"", arena);
  Dowa_HashMap_Push_Arena(resp, "cache-control", "no-store", arena);
  Dowa_HashMap_Push_Arena(resp, "x-content-type-options", "nosniff", arena);
  Dowa_HashMap_Push_Arena(resp, "body", pdf, arena);
  return resp;
}

// Joinable worker function for local image conversion.
void Simple_WebpConverter_Background(void *arg)
{
  File_Converter_Config *configuration = (File_Converter_Config *)arg;

  char cmd[1024];
  snprintf(cmd, sizeof(cmd), "ffmpeg -y -i %s -quality 80 %s 2>/tmp/error_log",
           configuration->input_path, configuration->output_path);
  Seobeo_Log(SEOBEO_INFO, "[MEDIA] Running FFmpeg: %s\n", cmd);
  configuration->result = system(cmd);

  Seobeo_Log(
      SEOBEO_INFO,
      "[MEDIA] FFmpeg result: %d\n",
      configuration->result);
  if (configuration->result != 0)
  {
    Seobeo_Log(SEOBEO_ERROR, "[MEDIA] ERROR: FFmpeg conversion failed\n");
    return;
  }
  Seobeo_Log(
      SEOBEO_INFO,
      "[MEDIA] Successfully converted to webp: %s\n",
      configuration->output_path);
}

Seobeo_Request_Entry *ConvertImageToWebP(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;

  if (!req)
  {
    Seobeo_Log(SEOBEO_ERROR, "Request is NULL\n");
    char *error_msg = "Internal error: no request data";
    Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
    Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena);
    return resp;
  }

  size_t req_length = Dowa_Array_Length(req);
  printf("Request has %zu entries\n", req_length);

  for (size_t i = 0; i < req_length; i++)
  {
    Seobeo_Log(SEOBEO_INFO, "  Key[%zu]: '%s'\n", i, req[i].key);
  }

  void *body_kv = Dowa_HashMap_Get_Ptr(req, "Body");
  if (!body_kv)
  {
    printf("ERROR: No 'Body' key found in request\n");

    char *error_msg = "No file data provided";
    Dowa_HashMap_Push_Arena(resp, "status", "400", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
    Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena);
    return resp;
  }

  void *cl_kv = Dowa_HashMap_Get_Ptr(req, "Content-Length");
  if (!cl_kv)
  {
    char *error_msg = "No Content-Length header";
    Dowa_HashMap_Push_Arena(resp, "status", "400", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
    Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena);
    return resp;
  }

  const char *file_data = ((Seobeo_Request_Entry*)body_kv)->value;
  const char *content_length_str = ((Seobeo_Request_Entry*)cl_kv)->value;
  size_t file_size = atoi(content_length_str);

  Seobeo_Log(SEOBEO_DEBUG, "Converting image, file_size=%zu bytes\n", file_size);

  int open_flags = O_RDWR | O_CREAT | O_EXCL;

  char *uuid4 = (char *)Dowa_Arena_Allocate(arena, UUID_LEN);
  uint32 seed =
      (uint32)time(NULL) ^
      (uint32)Seobeo_Thread_Current_Id() ^
      counter++;
  Dowa_String_UUID(seed, uuid4);
  char *input_path = Dowa_Arena_Allocate(arena, TMP_FILE_LENGTH);;
  snprintf(input_path, TMP_FILE_LENGTH, "/tmp/%s", uuid4);
  int input_fd = open(input_path, open_flags, 0600);
  if (input_fd == -1)
  {
    char *error_msg = "Failed to create temporary file";
    Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
    Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena);
    return resp;
  }
  write(input_fd, file_data, file_size);
  close(input_fd);


  uuid4 = (char *)Dowa_Arena_Allocate(arena, UUID_LEN);
  seed =
      (uint32)time(NULL) ^
      (uint32)Seobeo_Thread_Current_Id() ^
      counter++;
  Dowa_String_UUID(seed, uuid4);
  char *output_path = (char *)Dowa_Arena_Allocate(arena, TMP_FILE_LENGTH);;
  snprintf(output_path, TMP_FILE_LENGTH, "/tmp/%s.webp", uuid4);
  Seobeo_Log(SEOBEO_DEBUG, "output_path %s\n", output_path);
  Seobeo_Log(SEOBEO_DEBUG, "open_flags: 0x%x\n", open_flags);
  Seobeo_Log(SEOBEO_DEBUG, "input_path: %s\n", input_path);
  int output_fd = open(output_path, open_flags, 0600);
  Seobeo_Log(SEOBEO_DEBUG, "output_fd: %d\n", output_fd);
  if (output_fd == -1)
  {
    unlink(input_path);
    Seobeo_Log(SEOBEO_DEBUG, "errno: %d (%s)\n", errno, strerror(errno));
    char *error_msg = "Failed to create output file";
    Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
    Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena);
    return resp;
  }
  close(output_fd);

  File_Converter_Config *configuration = Dowa_Arena_Allocate(arena, sizeof(File_Converter_Config));
  configuration->input_path = input_path;
  configuration->output_path = output_path;
  configuration->result = -1;

  Seobeo_Thread *p_worker = Seobeo_Thread_Start(
      Simple_WebpConverter_Background,
      configuration,
      NULL);
  if (!p_worker ||
      Seobeo_Thread_Join(p_worker) != SEOBEO_WORKER_OK ||
      configuration->result != 0)
  {
    unlink(input_path);
    unlink(output_path);
    char *error_msg = "FFmpeg conversion failed";
    Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
    Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena);
    return resp;
  }

  FILE *out_file = fopen(output_path, "rb");
  if (!out_file)
  {
    unlink(input_path);
    unlink(output_path);
    char *error_msg = "Failed to read converted file";
    Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
    Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena);
    return resp;
  }
  fclose(out_file);

  unlink(input_path);
  char *filename = strrchr(output_path, '/') + 1;
  char *response_body = Dowa_Arena_Allocate(arena, 512);
  snprintf(response_body, 512,
           "{\"success\":true,\"download_url\":\"/api/download/%s\",\"expires\":\"10 minutes\"}",
           filename);
  Dowa_HashMap_Push_Arena(resp, "status", "200", arena);
  Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
  Dowa_HashMap_Push_Arena(resp, "body", response_body, arena);

  Seobeo_Log(SEOBEO_DEBUG, "Image converted, available at /api/download/%s\n", filename);

  return resp;
}

Seobeo_Request_Entry *ConvertVideoToMP4(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;

  void *body_kv = Dowa_HashMap_Get_Ptr(req, "Body");
  if (!body_kv)
  {
    char *error_msg = "No file data provided";
    Dowa_HashMap_Push_Arena(resp, "status", "400", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
    Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena);
    return resp;
  }

  // Get Content-Length to know the actual binary size
  void *cl_kv = Dowa_HashMap_Get_Ptr(req, "Content-Length");
  if (!cl_kv)
  {
    char *error_msg = "No Content-Length header";
    Dowa_HashMap_Push_Arena(resp, "status", "400", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
    Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena);
    return resp;
  }

  const char *file_data = ((Seobeo_Request_Entry*)body_kv)->value;
  const char *content_length_str = ((Seobeo_Request_Entry*)cl_kv)->value;
  size_t file_size = atoi(content_length_str);

  printf("DEBUG: Converting video, file_size=%zu bytes\n", file_size);

  int open_flags = O_RDWR | O_CREAT | O_EXCL;

  char *uuid4 = (char *)Dowa_Arena_Allocate(arena, UUID_LEN);
  uint32 seed =
      (uint32)time(NULL) ^
      (uint32)Seobeo_Thread_Current_Id() ^
      counter++;
  Dowa_String_UUID(seed, uuid4);
  char *input_path = Dowa_Arena_Allocate(arena, TMP_FILE_LENGTH);
  snprintf(input_path, TMP_FILE_LENGTH, "/tmp/%s", uuid4);
  Seobeo_Log(SEOBEO_DEBUG, "Input path: %s\n", input_path);

  int input_fd = open(input_path, open_flags, 0600);
  if (input_fd == -1)
  {
    Seobeo_Log(SEOBEO_DEBUG, "errno: %d (%s)\n", errno, strerror(errno));
    char *error_msg = "Failed to create temporary file";
    Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
    Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena);
    return resp;
  }

  write(input_fd, file_data, file_size);
  close(input_fd);

  seed =
      (uint32)time(NULL) ^
      (uint32)Seobeo_Thread_Current_Id() ^
      counter++;
  Dowa_String_UUID(seed, uuid4);
  char *output_path = (char *)Dowa_Arena_Allocate(arena, TMP_FILE_LENGTH);;
  snprintf(output_path, TMP_FILE_LENGTH, "/tmp/%s.mp4", uuid4);
  int output_fd = open(output_path, open_flags, 0600);
  if (output_fd == -1)
  {
    unlink(input_path);
    char *error_msg = "Failed to create output file";
    Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
    Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena);
    return resp;
  }
  close(output_fd);

  char cmd[512];
  snprintf(cmd, sizeof(cmd),
           "ffmpeg -y -i %s -c:v libx264 -preset fast -crf 23 -c:a aac %s 2>/tmp/error_log",
           input_path, output_path);
  int result = system(cmd);
  if (result != 0)
  {
    unlink(input_path);
    unlink(output_path);
    char *error_msg = "FFmpeg conversion failed";
    Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
    Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena);
    return resp;
  }

  unlink(input_path);
  char *filename = strrchr(output_path, '/') + 1;
  char *response_body = Dowa_Arena_Allocate(arena, 512);
  snprintf(response_body, 512,
           "{\"success\":true,\"download_url\":\"/api/download/%s\",\"expires\":\"10 minutes\"}",
           filename);
  Dowa_HashMap_Push_Arena(resp, "status", "200", arena);
  Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
  Dowa_HashMap_Push_Arena(resp, "body", response_body, arena);

  printf("DEBUG: Video converted, available at /api/download/%s\n", filename);
  return resp;
}

static boolean Converted_Filename_Is_Valid(const char *filename)
{
  if (!filename)
    return FALSE;
  const char *extension = strrchr(filename, '.');
  if (!extension || (strcmp(extension, ".webp") != 0 &&
                     strcmp(extension, ".mp4") != 0))
    return FALSE;
  if ((size_t)(extension - filename) != 36)
    return FALSE;
  for (size_t i = 0; i < 36; i++)
  {
    char value = filename[i];
    if (i == 8 || i == 13 || i == 18 || i == 23)
    {
      if (value != '-')
        return FALSE;
      continue;
    }
    if (!((value >= '0' && value <= '9') ||
          (value >= 'a' && value <= 'f') ||
          (value >= 'A' && value <= 'F')))
      return FALSE;
  }
  return TRUE;
}

static Seobeo_Request_Entry *Converted_File_Error(
    Dowa_Arena *arena,
    char *status,
    char *message)
{
  Seobeo_Request_Entry *resp = NULL;
  Dowa_HashMap_Push_Arena(resp, "status", status, arena);
  Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
  Dowa_HashMap_Push_Arena(resp, "body", message, arena);
  return resp;
}

Seobeo_Request_Entry *DeleteConvertedFile(
    Seobeo_Request_Entry *req,
    Dowa_Arena *arena)
{
  void *filename_kv = Dowa_HashMap_Get_Ptr(req, ":filename");
  const char *filename = filename_kv
      ? ((Seobeo_Request_Entry *)filename_kv)->value
      : NULL;
  if (!Converted_Filename_Is_Valid(filename))
    return Converted_File_Error(arena, "400", "Invalid converted filename");

  char filepath[512];
  snprintf(filepath, sizeof(filepath), "/tmp/%s", filename);
  if (unlink(filepath) != 0 && errno != ENOENT)
    return Converted_File_Error(arena, "500", "Unable to delete converted file");

  Seobeo_Request_Entry *resp = NULL;
  Dowa_HashMap_Push_Arena(resp, "status", "204", arena);
  Dowa_HashMap_Push_Arena(resp, "body", "", arena);
  return resp;
}

Seobeo_Request_Entry *DownloadConvertedFile(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;

  void *filename_kv = Dowa_HashMap_Get_Ptr(req, ":filename");
  if (!filename_kv)
  {
    char *error_msg = "No filename specified";
    Dowa_HashMap_Push_Arena(resp, "status", "404", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
    Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena);
    return resp;
  }

  const char *filename = ((Seobeo_Request_Entry*)filename_kv)->value;
  if (!Converted_Filename_Is_Valid(filename))
    return Converted_File_Error(arena, "400", "Invalid converted filename");

  char filepath[512];
  snprintf(filepath, sizeof(filepath), "/tmp/%s", filename);

  FILE *file = fopen(filepath, "rb");
  if (!file)
  {
    char *error_msg = "File not found or expired";
    Dowa_HashMap_Push_Arena(resp, "status", "404", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
    Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena);
    return resp;
  }

  fseek(file, 0, SEEK_END);
  size_t file_size = ftell(file);
  fseek(file, 0, SEEK_SET);

  char *file_data = malloc(file_size + 1);
  if (!file_data)
  {
    fclose(file);
    char *error_msg = "Memory allocation failed";
    Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
    Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena);
    return resp;
  }

  fread(file_data, 1, file_size, file);
  file_data[file_size] = '\0';
  fclose(file);

  char *content_type = "application/octet-stream";
  if (strcmp(strrchr(filename, '.'), ".webp") == 0)
    content_type = "image/webp";
  else if (strstr(filename, ".mp4"))
    content_type = "video/mp4";

  char *body = Dowa_Arena_Allocate(arena, file_size + 1);
  memcpy(body, file_data, file_size);
  body[file_size] = '\0';
  free(file_data);

  unlink(filepath);

  printf("DEBUG: Served and deleted file: %s (%zu bytes)\n", filename, file_size);

  char *content_length = Dowa_Arena_Allocate(arena, 32);
  snprintf(content_length, 32, "%zu", file_size);

  Dowa_HashMap_Push_Arena(resp, "status", "200", arena);
  Dowa_HashMap_Push_Arena(resp, "content-type", content_type, arena);
  Dowa_HashMap_Push_Arena(resp, "content-length", content_length, arena);
  Dowa_HashMap_Push_Arena(resp, "body", body, arena);

  return resp;
}

Seobeo_Request_Entry *RenderBlogList(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;
  char *final_body = Dowa_Arena_Allocate(arena, HTML_PAGE_CAP);
  if (!final_body || !Mjj_Template_Render_File(final_body, HTML_PAGE_CAP, "/blog/index.html", arena))
    return html_render_error(arena, "Internal Server Error");
  Dowa_HashMap_Push_Arena(resp, "body", final_body, arena);
  return resp;
}


Seobeo_Request_Entry *RenderBlog(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;

  char *file_path = Dowa_Arena_Allocate(arena, 1024);
  void *blog_id_kv = Dowa_HashMap_Get_Ptr(req, ":blog_id");
  char *blog_id = ((Seobeo_Request_Entry*)blog_id_kv)->value;
  snprintf(file_path, 1024, "/blog/%s/index.html", blog_id);

  char *final_body = Dowa_Arena_Allocate(arena, HTML_PAGE_CAP);
  if (!final_body || !Mjj_Template_Render_File(final_body, HTML_PAGE_CAP, file_path, arena))
  {
    Seobeo_Request_Entry *err = NULL;
    Dowa_HashMap_Push_Arena(err, "status", "404", arena);
    Dowa_HashMap_Push_Arena(err, "content-type", "text/plain; charset=utf-8", arena);
    Dowa_HashMap_Push_Arena(err, "body", "Not found", arena);
    return err;
  }
  Dowa_HashMap_Push_Arena(resp, "body", final_body, arena);
  return resp;
}

void Chat_Handler(Seobeo_WebSocket_Server_Connection *p_conn, Seobeo_WebSocket_Message *p_msg, void *p_user_data)
{
  (void)p_user_data;

  if (p_msg->opcode == SEOBEO_WS_OPCODE_TEXT)
  {
    char message[2048];
    snprintf(message, sizeof(message), "[%s]: %.*s", p_conn->client_id, (int)p_msg->length, (char*)p_msg->data);

    Seobeo_Log(SEOBEO_INFO, "[Chat] Broadcasting: %s\n", message);
    Seobeo_WebSocket_Server_Broadcast_Text(message, p_conn);
  }
}

Seobeo_Request_Entry *GetTalk(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;
  char *final_body = Dowa_Arena_Allocate(arena, HTML_PAGE_CAP);
  if (!final_body || !Mjj_Template_Render_File(final_body, HTML_PAGE_CAP, "/talk/index.html", arena))
    return html_render_error(arena, "Internal Server Error");
  Dowa_HashMap_Push_Arena(resp, "body", final_body, arena);
  return resp;
}

typedef struct {
  const char *name;
  const char *title;
  const char *copy;
  const char *works;
} Jrpg_Initial_Panel;

static boolean Mjj_Replace_All(
    char *buffer,
    size_t capacity,
    const char *needle,
    const char *replacement)
{
  if (!buffer || !needle || !replacement || needle[0] == '\0')
    return FALSE;

  size_t needle_length = strlen(needle);
  size_t replacement_length = strlen(replacement);
  char *match = strstr(buffer, needle);
  while (match)
  {
    size_t current_length = strlen(buffer);
    size_t offset = (size_t)(match - buffer);
    size_t new_length =
        current_length - needle_length + replacement_length;
    if (new_length >= capacity)
      return FALSE;

    memmove(
        match + replacement_length,
        match + needle_length,
        current_length - offset - needle_length + 1);
    memcpy(match, replacement, replacement_length);
    match = strstr(match + replacement_length, needle);
  }
  return TRUE;
}

static const Jrpg_Initial_Panel *Jrpg_Resolve_Initial_Panel(
    Seobeo_Request_Entry *req)
{
  static const Jrpg_Initial_Panel panels[] = {
    {
      "resume",
      "Resume",
      "Member of Technical Staff and engineering leader with 10+ years "
      "building AI agent platforms and production systems across Microsoft, "
      "Meta, Google, and growth-stage companies.",
      "<li><a href=\"/resume\" data-resume-modal>"
      "<span>Full resume</span><small>Career dossier</small></a></li>"
      "<li><a href=\"https://www.microsoft.com/en-us/microsoft-copilot/blog/"
      "2026/02/26/copilot-tasks-from-answers-to-actions/\">"
      "<span>Copilot Tasks</span><small>Agentic execution</small></a></li>"
    },
    {
      "tools",
      "Tools",
      "Useful browser tools backed by first-party C, WASM, media, and "
      "document-processing systems.",
      "<li><a href=\"/tools/markdown_to_html\" data-latest-tool "
      "data-tool-url=\"/tools/markdown_to_html\">"
      "<span>Markdown</span><small>Writing</small></a></li>"
      "<li><a href=\"/tools/file_converter\" data-latest-tool "
      "data-tool-url=\"/tools/file_converter\">"
      "<span>Converter</span><small>Media</small></a></li>"
      "<li><a href=\"/tools/hls_player\" data-latest-tool "
      "data-tool-url=\"/tools/hls_player\">"
      "<span>HLS Player</span><small>Streaming</small></a></li>"
    },
    {
      "blog",
      "Blogs",
      "Technical writing about networking, rendering, performance, developer "
      "tooling, and experiments.",
      "<li><a href=\"/blog\" data-blog-archive>"
      "<span>All posts</span><small>Archive</small></a></li>"
    },
    {
      "conversations",
      "Resume",
      "",
      ""
    },
  };

  const char *requested = NULL;
  void *panel_kv = Dowa_HashMap_Get_Ptr(req, "query_panel");
  if (panel_kv)
    requested = ((Seobeo_Request_Entry *)panel_kv)->value;

  for (size_t i = 0; i < sizeof(panels) / sizeof(panels[0]); ++i)
  {
    if (requested && strcmp(requested, panels[i].name) == 0)
      return &panels[i];
  }
  return &panels[0];
}

Seobeo_Request_Entry *GetJrpg(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;
  char *final_body = Dowa_Arena_Allocate(arena, HTML_PAGE_CAP);
  if (!final_body || !Mjj_Template_Render_File(final_body, HTML_PAGE_CAP, "/jrpg/index.html", arena))
    return html_render_error(arena, "Internal Server Error");

  const Jrpg_Initial_Panel *panel = Jrpg_Resolve_Initial_Panel(req);
  boolean conversations =
      strcmp(panel->name, "conversations") == 0 ? TRUE : FALSE;
  const char *preview_selection = conversations ? "resume" : panel->name;
  struct {
    const char *token;
    const char *value;
  } replacements[] = {
    {"__MJJ_PANEL__", panel->name},
    {"__MJJ_PREVIEW_SELECTION__", preview_selection},
    {"__MJJ_PREVIEW_TITLE__", panel->title},
    {"__MJJ_PREVIEW_COPY__", panel->copy},
    {"__MJJ_PREVIEW_WORKS__", panel->works},
    {"__MJJ_PREVIEW_HIDDEN__", conversations ? "hidden" : ""},
    {"__MJJ_ARCHIVE_HIDDEN__", conversations ? "" : "hidden"},
    {"__MJJ_RESUME_PRESSED__",
      strcmp(panel->name, "resume") == 0 ? "true" : "false"},
    {"__MJJ_TOOLS_PRESSED__",
      strcmp(panel->name, "tools") == 0 ? "true" : "false"},
    {"__MJJ_BLOG_PRESSED__",
      strcmp(panel->name, "blog") == 0 ? "true" : "false"},
    {"__MJJ_CONVERSATIONS_PRESSED__", conversations ? "true" : "false"},
  };
  for (size_t i = 0;
       i < sizeof(replacements) / sizeof(replacements[0]);
       ++i)
  {
    if (!Mjj_Replace_All(
          final_body,
          HTML_PAGE_CAP,
          replacements[i].token,
          replacements[i].value))
      return html_render_error(arena, "Internal Server Error");
  }
  Dowa_HashMap_Push_Arena(resp, "body", final_body, arena);
  Dowa_HashMap_Push_Arena(resp, "referrer-policy", "no-referrer", arena);
  return resp;
}

Seobeo_Request_Entry *GetLogin(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  (void)req;
  Seobeo_Request_Entry *resp = NULL;
  char *final_body = Dowa_Arena_Allocate(arena, HTML_PAGE_CAP);
  if (!final_body || !Mjj_Template_Render_File(final_body, HTML_PAGE_CAP, "/login/index.html", arena))
  {
    Seobeo_Request_Entry *err = NULL;
    Dowa_HashMap_Push_Arena(err, "status", "500", arena);
    Dowa_HashMap_Push_Arena(err, "content-type", "text/plain; charset=utf-8", arena);
    Dowa_HashMap_Push_Arena(err, "cache-control", "no-store", arena);
    Dowa_HashMap_Push_Arena(err, "body", "Internal Server Error", arena);
    return err;
  }
  Dowa_HashMap_Push_Arena(resp, "body", final_body, arena);
  Dowa_HashMap_Push_Arena(
      resp, "content-type", "text/html; charset=utf-8", arena);
  Dowa_HashMap_Push_Arena(resp, "cache-control", "no-store", arena);
  Dowa_HashMap_Push_Arena(resp, "pragma", "no-cache", arena);
  Dowa_HashMap_Push_Arena(resp, "x-content-type-options", "nosniff", arena);
  Dowa_HashMap_Push_Arena(resp, "referrer-policy", "no-referrer", arena);
  Dowa_HashMap_Push_Arena(
      resp, "content-security-policy", "frame-ancestors 'none'", arena);
  return resp;
}

Seobeo_Request_Entry *GetNotesLogin(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;
  char *final_body = Dowa_Arena_Allocate(arena, HTML_PAGE_CAP);
  if (!final_body || !Mjj_Template_Render_File(final_body, HTML_PAGE_CAP, "/notes/login.html", arena))
    return html_render_error(arena, "Internal Server Error");
  Dowa_HashMap_Push_Arena(resp, "body", final_body, arena);
  return resp;
}

Seobeo_Request_Entry *GetNotes(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;
  char *final_body = Dowa_Arena_Allocate(arena, HTML_PAGE_CAP);
  if (!final_body || !Mjj_Template_Render_File(final_body, HTML_PAGE_CAP, "/notes/index.html", arena))
    return html_render_error(arena, "Internal Server Error");
  Dowa_HashMap_Push_Arena(resp, "body", final_body, arena);
  return resp;
}

Seobeo_Request_Entry *GetNoteById(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;
  char *final_body = Dowa_Arena_Allocate(arena, HTML_PAGE_CAP);
  if (!final_body || !Mjj_Template_Render_File(final_body, HTML_PAGE_CAP, "/notes/index.html", arena))
    return html_render_error(arena, "Internal Server Error");
  Dowa_HashMap_Push_Arena(resp, "body", final_body, arena);
  return resp;
}

CREATE_REDIRECT_HANDLER(HomePage, "/")
CREATE_REDIRECT_HANDLER(Resume, "/resume")
CREATE_REDIRECT_HANDLER(Tools, "/tools")
CREATE_REDIRECT_HANDLER(MarkDownToHtml, "/tools/markdown_to_html")
CREATE_REDIRECT_HANDLER(FileConverter, "/tools/file_converter")
CREATE_REDIRECT_HANDLER(HlsPlayer, "/tools/hls_player")
CREATE_REDIRECT_HANDLER(LatexEditor, "/tools/latex_editor")
CREATE_REDIRECT_HANDLER(Talk, "/talk")
CREATE_REDIRECT_HANDLER(Jrpg, "/jrpg")
CREATE_REDIRECT_HANDLER(Editor, "/editor")

// S3 Upload URL API
// POST /api/s3/upload-url
// Headers: Authorization: Bearer <token>, Content-Type: application/json
// Body: {"filename": "photo.png", "content_type": "image/png"}
// Returns: {"upload_url": "https://...", "key": "uploads/..."}
Seobeo_Request_Entry *GetS3UploadUrl(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;

  // Check auth token
  void *auth_kv = Dowa_HashMap_Get_Ptr(req, "Authorization");
  if (!auth_kv)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "401", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Missing Authorization header\"}", arena);
    return resp;
  }

  const char *auth_header = ((Seobeo_Request_Entry*)auth_kv)->value;

  // Expect "Bearer <token>"
  if (strncmp(auth_header, "Bearer ", 7) != 0)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "401", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Invalid Authorization format, use Bearer token\"}", arena);
    return resp;
  }

  const char *token = auth_header + 7;
  if (strlen(g_upload_auth_token) == 0 || strcmp(token, g_upload_auth_token) != 0)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "403", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Invalid token\"}", arena);
    return resp;
  }

  // Parse request body for filename and content_type
  void *body_kv = Dowa_HashMap_Get_Ptr(req, "Body");
  if (!body_kv)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "400", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Missing request body\"}", arena);
    return resp;
  }

  const char *body = ((Seobeo_Request_Entry*)body_kv)->value;

  // Simple JSON parsing for filename and content_type
  char filename[256] = {0};
  char content_type[128] = "application/octet-stream";

  // Find "filename":"value"
  const char *fn_key = strstr(body, "\"filename\"");
  if (fn_key)
  {
    const char *fn_start = strchr(fn_key + 10, '"');
    if (fn_start)
    {
      fn_start++;
      const char *fn_end = strchr(fn_start, '"');
      if (fn_end && (size_t)(fn_end - fn_start) < sizeof(filename))
      {
        memcpy(filename, fn_start, fn_end - fn_start);
        filename[fn_end - fn_start] = '\0';
      }
    }
  }

  // Find "content_type":"value"
  const char *ct_key = strstr(body, "\"content_type\"");
  if (ct_key)
  {
    const char *ct_start = strchr(ct_key + 14, '"');
    if (ct_start)
    {
      ct_start++;
      const char *ct_end = strchr(ct_start, '"');
      if (ct_end && (size_t)(ct_end - ct_start) < sizeof(content_type))
      {
        memcpy(content_type, ct_start, ct_end - ct_start);
        content_type[ct_end - ct_start] = '\0';
      }
    }
  }

  if (strlen(filename) == 0)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "400", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Missing filename in request body\"}", arena);
    return resp;
  }

  // Generate unique S3 key with timestamp
  char s3_key[512];
  char *uuid = Dowa_Arena_Allocate(arena, UUID_LEN);
  uint32 seed =
      (uint32)time(NULL) ^
      (uint32)Seobeo_Thread_Current_Id() ^
      counter++;
  Dowa_String_UUID(seed, uuid);
  snprintf(s3_key, sizeof(s3_key), "uploads/%s/%s", uuid, filename);

  // Generate presigned URL
  S3_Presigned_URL presigned = S3_Presign_Put(&g_s3_config, s3_key, content_type, g_s3_url_expires);

  if (!presigned.success)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    char *error_body = Dowa_Arena_Allocate(arena, 256);
    snprintf(error_body, 256, "{\"error\":\"Failed to generate upload URL: %s\"}",
             presigned.error_message ? presigned.error_message : "unknown");
    Dowa_HashMap_Push_Arena(resp, "body", error_body, arena);
    S3_Presigned_URL_Destroy(&presigned);
    return resp;
  }

  // Build public URL using CloudFront
  char public_url[512];
  if (g_s3_cloudfront_url[0])
  {
    snprintf(public_url, sizeof(public_url), "%s/%s", g_s3_cloudfront_url, s3_key);
  }
  else
  {
    snprintf(public_url, sizeof(public_url), "https://%s.s3.%s.amazonaws.com/%s",
             g_s3_bucket, g_s3_region, s3_key);
  }

  // Build response
  char *response_body = Dowa_Arena_Allocate(arena, 4096 + strlen(presigned.url));
  snprintf(response_body, 4096 + strlen(presigned.url),
           "{\"upload_url\":\"%s\",\"public_url\":\"%s\",\"key\":\"%s\",\"expires\":%d}",
           presigned.url, public_url, s3_key, g_s3_url_expires);

  S3_Presigned_URL_Destroy(&presigned);

  Dowa_HashMap_Push_Arena(resp, "status", "200", arena);
  Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
  Dowa_HashMap_Push_Arena(resp, "body", response_body, arena);

  printf("[S3] Generated upload URL for: %s\n", s3_key);

  return resp;
}

// Editor Content Save API
// POST /api/editor/save
// Headers: Authorization: Bearer <token>
// Body: {"doc_id": "my-doc", "content": "<html content>"}
Seobeo_Request_Entry *EditorSave(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;

  // Check auth token
  void *auth_kv = Dowa_HashMap_Get_Ptr(req, "Authorization");
  if (!auth_kv)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "401", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Missing Authorization header\"}", arena);
    return resp;
  }

  const char *auth_header = ((Seobeo_Request_Entry*)auth_kv)->value;
  if (strncmp(auth_header, "Bearer ", 7) != 0)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "401", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Invalid Authorization format\"}", arena);
    return resp;
  }

  const char *token = auth_header + 7;
  if (strlen(g_upload_auth_token) == 0 || strcmp(token, g_upload_auth_token) != 0)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "403", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Invalid token\"}", arena);
    return resp;
  }

  if (!g_db_connection)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Database not available\"}", arena);
    return resp;
  }

  // Parse request body
  void *body_kv = Dowa_HashMap_Get_Ptr(req, "Body");
  if (!body_kv)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "400", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Missing request body\"}", arena);
    return resp;
  }

  const char *body = ((Seobeo_Request_Entry*)body_kv)->value;

  // Parse doc_id and content from JSON
  char doc_id[256] = "default";
  char *content = NULL;
  size_t content_len = 0;

  // Find "doc_id":"value"
  const char *doc_key = strstr(body, "\"doc_id\"");
  if (doc_key)
  {
    const char *doc_start = strchr(doc_key + 8, '"');
    if (doc_start)
    {
      doc_start++;
      const char *doc_end = strchr(doc_start, '"');
      if (doc_end && (size_t)(doc_end - doc_start) < sizeof(doc_id))
      {
        memcpy(doc_id, doc_start, doc_end - doc_start);
        doc_id[doc_end - doc_start] = '\0';
      }
    }
  }

  // Find "content":"value" - content can be large and contain escaped characters
  const char *content_key = strstr(body, "\"content\"");
  if (content_key)
  {
    const char *content_start = strchr(content_key + 9, '"');
    if (content_start)
    {
      content_start++;
      // Find closing quote (accounting for escaped quotes)
      const char *p = content_start;
      while (*p)
      {
        if (*p == '\\' && *(p+1))
        {
          p += 2;
          continue;
        }
        if (*p == '"') break;
        p++;
      }
      content_len = p - content_start;
      content = Dowa_Arena_Allocate(arena, content_len + 1);
      memcpy(content, content_start, content_len);
      content[content_len] = '\0';
    }
  }

  if (!content)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "400", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Missing content\"}", arena);
    return resp;
  }

  // Upsert content
  const char *upsert_query =
    "INSERT INTO editor_content (access_token, doc_id, content, updated_at) "
    "VALUES (?, ?, ?, strftime('%s', 'now')) "
    "ON CONFLICT(access_token, doc_id) DO UPDATE SET "
    "content = excluded.content, updated_at = strftime('%s', 'now')";

  const char *params[] = { token, doc_id, content };
  int32 result = Deita_Query_Execute_Update_Prepared(g_db_connection, upsert_query, 3, params);

  if (result < 0)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Failed to save\"}", arena);
    return resp;
  }

  printf("[EDITOR] Saved doc_id=%s, content_len=%zu\n", doc_id, content_len);

  Dowa_HashMap_Push_Arena(resp, "status", "200", arena);
  Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
  Dowa_HashMap_Push_Arena(resp, "body", "{\"success\":true}", arena);
  return resp;
}

// Editor Content Load API
// GET /api/editor/load/:doc_id
// Headers: Authorization: Bearer <token>
Seobeo_Request_Entry *EditorLoad(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;

  // Check auth token
  void *auth_kv = Dowa_HashMap_Get_Ptr(req, "Authorization");
  if (!auth_kv)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "401", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Missing Authorization header\"}", arena);
    return resp;
  }

  const char *auth_header = ((Seobeo_Request_Entry*)auth_kv)->value;
  if (strncmp(auth_header, "Bearer ", 7) != 0)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "401", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Invalid Authorization format\"}", arena);
    return resp;
  }

  const char *token = auth_header + 7;
  if (strlen(g_upload_auth_token) == 0 || strcmp(token, g_upload_auth_token) != 0)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "403", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Invalid token\"}", arena);
    return resp;
  }

  if (!g_db_connection)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Database not available\"}", arena);
    return resp;
  }

  // Get doc_id from URL parameter
  void *doc_id_kv = Dowa_HashMap_Get_Ptr(req, ":doc_id");
  const char *doc_id = "default";
  if (doc_id_kv)
  {
    doc_id = ((Seobeo_Request_Entry*)doc_id_kv)->value;
  }

  // Query content
  const char *select_query =
    "SELECT content, updated_at FROM editor_content WHERE access_token = ? AND doc_id = ?";
  const char *params[] = { token, doc_id };

  Deita_Result_Set *p_result = Deita_Query_Execute_Prepared(g_db_connection, select_query, 2, params, arena);

  if (p_result && Deita_Result_Set_Next(p_result))
  {
    const char *content = Deita_Result_Set_Get_Text(p_result, 0);
    int64 updated_at = Deita_Result_Set_Get_Integer(p_result, 1);

    // Build JSON response - escape content
    size_t content_len = content ? strlen(content) : 0;
    char *response_body = Dowa_Arena_Allocate(arena, content_len + 256);
    snprintf(response_body, content_len + 256,
             "{\"doc_id\":\"%s\",\"content\":\"%s\",\"updated_at\":%lld}",
             doc_id, content ? content : "", (long long)updated_at);

    Dowa_HashMap_Push_Arena(resp, "status", "200", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", response_body, arena);

    printf("[EDITOR] Loaded doc_id=%s\n", doc_id);
  }
  else
  {
    // No content found, return empty
    char *response_body = Dowa_Arena_Allocate(arena, 128);
    snprintf(response_body, 128, "{\"doc_id\":\"%s\",\"content\":\"\",\"updated_at\":0}", doc_id);

    Dowa_HashMap_Push_Arena(resp, "status", "200", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", response_body, arena);
  }

  if (p_result) Deita_Result_Set_Free(p_result);
  return resp;
}

// Media Upload API - Create media record
// POST /api/media/create
// Headers: Authorization: Bearer <token>, Content-Type: application/json
// Body: {"filename": "photo.jpg", "content_type": "image/jpeg"}
// Returns: {"media_id": 123, "upload_url": "https://...", "expires": 3600}
Seobeo_Request_Entry *MediaCreate(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;

  // Check auth token
  void *auth_kv = Dowa_HashMap_Get_Ptr(req, "Authorization");
  if (!auth_kv)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "401", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Missing Authorization header\"}", arena);
    return resp;
  }

  const char *auth_header = ((Seobeo_Request_Entry*)auth_kv)->value;
  if (strncmp(auth_header, "Bearer ", 7) != 0)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "401", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Invalid Authorization format\"}", arena);
    return resp;
  }

  const char *token = auth_header + 7;
  if (strlen(g_upload_auth_token) == 0 || strcmp(token, g_upload_auth_token) != 0)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "403", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Invalid token\"}", arena);
    return resp;
  }

  if (!g_db_connection)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Database not available\"}", arena);
    return resp;
  }

  // Parse request body
  void *body_kv = Dowa_HashMap_Get_Ptr(req, "Body");
  if (!body_kv)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "400", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Missing request body\"}", arena);
    return resp;
  }

  const char *body = ((Seobeo_Request_Entry*)body_kv)->value;

  // Parse filename and content_type
  char filename[256] = {0};
  char content_type[128] = "application/octet-stream";

  // Find "filename":"value"
  const char *fn_key = strstr(body, "\"filename\"");
  if (fn_key)
  {
    const char *fn_start = strchr(fn_key + 10, '"');
    if (fn_start)
    {
      fn_start++;
      const char *fn_end = strchr(fn_start, '"');
      if (fn_end && (size_t)(fn_end - fn_start) < sizeof(filename))
      {
        memcpy(filename, fn_start, fn_end - fn_start);
        filename[fn_end - fn_start] = '\0';
      }
    }
  }

  // Find "content_type":"value"
  const char *ct_key = strstr(body, "\"content_type\"");
  if (ct_key)
  {
    const char *ct_start = strchr(ct_key + 14, '"');
    if (ct_start)
    {
      ct_start++;
      const char *ct_end = strchr(ct_start, '"');
      if (ct_end && (size_t)(ct_end - ct_start) < sizeof(content_type))
      {
        memcpy(content_type, ct_start, ct_end - ct_start);
        content_type[ct_end - ct_start] = '\0';
      }
    }
  }

  if (strlen(filename) == 0)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "400", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Missing filename\"}", arena);
    return resp;
  }

  // Generate UUID for this upload
  char *uuid = Dowa_Arena_Allocate(arena, UUID_LEN);
  uint32 seed =
      (uint32)time(NULL) ^
      (uint32)Seobeo_Thread_Current_Id() ^
      counter++;
  Dowa_String_UUID(seed, uuid);

  // Generate S3 keys
  char s3_key_original[512];
  char s3_key_processed[512];
  snprintf(s3_key_original, sizeof(s3_key_original), "uploads/%s/%s", uuid, filename);

  // Only use .webp for images
  int is_image = (strncmp(content_type, "image/", 6) == 0);
  if (is_image)
  {
    snprintf(s3_key_processed, sizeof(s3_key_processed), "uploads/%s/processed.webp", uuid);
  }
  else
  {
    s3_key_processed[0] = '\0'; // No processed version for non-images
  }

  // Insert into database
  const char *insert_query =
    "INSERT INTO media_uploads (access_token, original_filename, content_type, s3_key_original, s3_key_processed, status) "
    "VALUES (?, ?, ?, ?, ?, 'pending') RETURNING id";

  const char *params[] = { token, filename, content_type, s3_key_original, s3_key_processed };
  Deita_Result_Set *id_result = Deita_Query_Execute_Prepared(
      g_db_connection,
      insert_query,
      5,
      params,
      arena);
  if (!id_result || !Deita_Result_Set_Next(id_result))
  {
    if (id_result) Deita_Result_Set_Free(id_result);
    Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Failed to create media record\"}", arena);
    return resp;
  }

  int64 media_id = Deita_Result_Set_Get_Integer(id_result, 0);
  Deita_Result_Set_Free(id_result);

  // Generate presigned PUT URL
  S3_Presigned_URL presigned = S3_Presign_Put(&g_s3_config, s3_key_original, content_type, g_s3_url_expires);

  if (!presigned.success)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    char *error_body = Dowa_Arena_Allocate(arena, 256);
    snprintf(error_body, 256, "{\"error\":\"Failed to generate upload URL: %s\"}",
             presigned.error_message ? presigned.error_message : "unknown");
    Dowa_HashMap_Push_Arena(resp, "body", error_body, arena);
    S3_Presigned_URL_Destroy(&presigned);
    return resp;
  }

  // Build public URL using CloudFront or S3
  char public_url[512];
  if (g_s3_cloudfront_url[0])
  {
    snprintf(public_url, sizeof(public_url), "%s/%s", g_s3_cloudfront_url, s3_key_original);
  }
  else
  {
    snprintf(public_url, sizeof(public_url), "https://%s.s3.%s.amazonaws.com/%s",
             g_s3_bucket, g_s3_region, s3_key_original);
  }

  // Build response
  char *response_body = Dowa_Arena_Allocate(arena, 4096 + strlen(presigned.url) + strlen(public_url));
  snprintf(response_body, 4096 + strlen(presigned.url) + strlen(public_url),
           "{\"media_id\":%lld,\"upload_url\":\"%s\",\"public_url\":\"%s\",\"expires\":%d}",
           (long long)media_id, presigned.url, public_url, g_s3_url_expires);

  S3_Presigned_URL_Destroy(&presigned);

  Dowa_HashMap_Push_Arena(resp, "status", "200", arena);
  Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
  Dowa_HashMap_Push_Arena(resp, "body", response_body, arena);

  printf("[MEDIA] Created media_id=%lld, file=%s\n", (long long)media_id, filename);

  return resp;
}

// Worker-pool task for S3 media processing.
void Media_Process_Background(void *arg)
{
  Media_Processing_Context *ctx = (Media_Processing_Context *)arg;

  Seobeo_Log(SEOBEO_INFO, "[MEDIA] Background worker started for media_id=%lld\n", (long long)ctx->media_id);
  Seobeo_Log(SEOBEO_INFO, "[MEDIA] S3 key original: %s\n", ctx->s3_key_original);
  Seobeo_Log(SEOBEO_INFO, "[MEDIA] S3 key processed: %s\n", ctx->s3_key_processed);
  Seobeo_Log(SEOBEO_INFO, "[MEDIA] DB path: %s\n", ctx->db_path);

  // Open a worker-local DB connection.
  Deita_Connection *db_conn = Deita_Connection_Create(DEITA_DATABASE_TYPE_SQLITE3, ctx->db_path);
  if (!db_conn || !Deita_Connection_Is_Open(db_conn))
  {
    Seobeo_Log(SEOBEO_ERROR, "[MEDIA] Worker ERROR: Failed to open database for media_id=%lld\n", (long long)ctx->media_id);
    return;
  }

  // Update status to 'processing'
  const char *update_processing =
    "UPDATE media_uploads SET status='processing', updated_at=strftime('%s','now') WHERE id=?";
  char media_id_str[32];
  snprintf(media_id_str, sizeof(media_id_str), "%lld", (long long)ctx->media_id);
  const char *params[] = { media_id_str };
  int32 update_result = Deita_Query_Execute_Update_Prepared(db_conn, update_processing, 1, params);
  Seobeo_Log(SEOBEO_INFO, "[MEDIA] Updated status to 'processing' for media_id=%lld (result=%d)\n", (long long)ctx->media_id, update_result);

  // Generate presigned GET URL for download (10 min expiry)
  Seobeo_Log(SEOBEO_INFO, "[MEDIA] Generating presigned GET URL for media_id=%lld\n", (long long)ctx->media_id);
  S3_Presigned_URL download_url = S3_Presign_Get(&ctx->s3_config, ctx->s3_key_original, 600);
  if (!download_url.success)
  {
    const char *error_msg = download_url.error_message ? download_url.error_message : "Failed to generate download URL";
    Seobeo_Log(SEOBEO_ERROR, "[MEDIA] ERROR: Failed to generate download URL for media_id=%lld: %s\n",
               (long long)ctx->media_id, error_msg);
    const char *update_error =
      "UPDATE media_uploads SET status='error', error_message=?, updated_at=strftime('%s','now') WHERE id=?";
    const char *error_params[] = { error_msg, media_id_str };
    Deita_Query_Execute_Update_Prepared(db_conn, update_error, 2, error_params);
    S3_Presigned_URL_Destroy(&download_url);
    Deita_Connection_Close(db_conn);
    return;
  }
  Seobeo_Log(SEOBEO_INFO, "[MEDIA] Generated presigned URL: %.100s...\n", download_url.url);

  // Generate temp file paths
  char tmp_input[256];
  char tmp_output[256];
  char *uuid_input = malloc(UUID_LEN);
  char *uuid_output = malloc(UUID_LEN);
  uint32 seed1 =
      (uint32)time(NULL) ^
      (uint32)Seobeo_Thread_Current_Id() ^
      counter++;
  uint32 seed2 =
      (uint32)time(NULL) ^
      (uint32)Seobeo_Thread_Current_Id() ^
      counter++;
  Dowa_String_UUID(seed1, uuid_input);
  Dowa_String_UUID(seed2, uuid_output);
  snprintf(tmp_input, sizeof(tmp_input), "/tmp/%s", uuid_input);
  snprintf(tmp_output, sizeof(tmp_output), "/tmp/%s.webp", uuid_output);
  free(uuid_input);
  free(uuid_output);

  // Download from S3
  Seobeo_Log(SEOBEO_INFO, "[MEDIA] Downloading from S3 to %s for media_id=%lld\n", tmp_input, (long long)ctx->media_id);
  Seobeo_Client_Request *download_req = Seobeo_Client_Request_Create(download_url.url);
  Seobeo_Client_Request_Set_Download_Path(download_req, tmp_input);
  Seobeo_Client_Response *download_resp = Seobeo_Client_Request_Execute(download_req);

  S3_Presigned_URL_Destroy(&download_url);

  if (!download_resp || download_resp->status_code != 200)
  {
    int status = download_resp ? download_resp->status_code : 0;
    Seobeo_Log(SEOBEO_ERROR, "[MEDIA] ERROR: Failed to download from S3 for media_id=%lld (status=%d)\n",
               (long long)ctx->media_id, status);
    const char *update_error =
      "UPDATE media_uploads SET status='error', error_message=?, updated_at=strftime('%s','now') WHERE id=?";
    const char *error_params[] = { "Failed to download from S3", media_id_str };
    Deita_Query_Execute_Update_Prepared(db_conn, update_error, 2, error_params);
    if (download_req) Seobeo_Client_Request_Destroy(download_req);
    if (download_resp) Seobeo_Client_Response_Destroy(download_resp);
    unlink(tmp_input);
    Deita_Connection_Close(db_conn);
    return;
  }

  Seobeo_Log(SEOBEO_INFO, "[MEDIA] Successfully downloaded file to %s\n", tmp_input);
  Seobeo_Client_Request_Destroy(download_req);
  Seobeo_Client_Response_Destroy(download_resp);

  // Convert to webp using FFmpeg
  char cmd[1024];
  char log_file[256];
  snprintf(log_file, sizeof(log_file), "/tmp/ffmpeg_%lld.log", (long long)ctx->media_id);
  snprintf(cmd, sizeof(cmd), "ffmpeg -y -i %s -quality 80 %s 2>%s",
           tmp_input, tmp_output, log_file);

  Seobeo_Log(SEOBEO_INFO, "[MEDIA] Running FFmpeg: %s\n", cmd);
  int ffmpeg_result = system(cmd);
  Seobeo_Log(SEOBEO_INFO, "[MEDIA] FFmpeg result: %d for media_id=%lld\n", ffmpeg_result, (long long)ctx->media_id);

  if (ffmpeg_result != 0)
  {
    Seobeo_Log(SEOBEO_ERROR, "[MEDIA] ERROR: FFmpeg conversion failed for media_id=%lld (exit code %d). Check log: %s\n",
               (long long)ctx->media_id, ffmpeg_result, log_file);
    const char *update_error =
      "UPDATE media_uploads SET status='error', error_message=?, updated_at=strftime('%s','now') WHERE id=?";
    const char *error_params[] = { "Image conversion failed", media_id_str };
    Deita_Query_Execute_Update_Prepared(db_conn, update_error, 2, error_params);
    unlink(tmp_input);
    unlink(tmp_output);
    Deita_Connection_Close(db_conn);
    return;
  }
  Seobeo_Log(SEOBEO_INFO, "[MEDIA] Successfully converted to webp: %s\n", tmp_output);

  // Upload processed file to S3
  Seobeo_Log(SEOBEO_INFO, "[MEDIA] Uploading processed file to S3: %s -> %s\n", tmp_output, ctx->s3_key_processed);
  S3_Result upload_result = S3_Upload_File_With_Content_Type(
    &ctx->s3_config, tmp_output, ctx->s3_key_processed, "image/webp");

  if (!upload_result.success)
  {
    const char *error_msg = upload_result.error_message ? upload_result.error_message : "Failed to upload processed file";
    Seobeo_Log(SEOBEO_ERROR, "[MEDIA] ERROR: Failed to upload processed file for media_id=%lld: %s (HTTP status: %d)\n",
               (long long)ctx->media_id, error_msg, upload_result.status_code);
    const char *update_error =
      "UPDATE media_uploads SET status='error', error_message=?, updated_at=strftime('%s','now') WHERE id=?";
    const char *error_params[] = { error_msg, media_id_str };
    Deita_Query_Execute_Update_Prepared(db_conn, update_error, 2, error_params);
    unlink(tmp_input);
    unlink(tmp_output);
    Deita_Connection_Close(db_conn);
    return;
  }

  Seobeo_Log(SEOBEO_INFO, "[MEDIA] Successfully uploaded processed file to S3\n");

  // Update status to 'finished'
  const char *update_finished =
    "UPDATE media_uploads SET status='finished', updated_at=strftime('%s','now') WHERE id=?";
  Deita_Query_Execute_Update_Prepared(db_conn, update_finished, 1, params);

  Seobeo_Log(SEOBEO_INFO, "[MEDIA] Successfully processed media_id=%lld - COMPLETE\n", (long long)ctx->media_id);

  // Cleanup
  unlink(tmp_input);
  unlink(tmp_output);
  Deita_Connection_Close(db_conn);
}

// Media Upload API - Mark uploaded
// POST /api/media/:id/uploaded
// Headers: Authorization: Bearer <token>
Seobeo_Request_Entry *MediaUploaded(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;

  // Check auth token
  void *auth_kv = Dowa_HashMap_Get_Ptr(req, "Authorization");
  if (!auth_kv)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "401", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Missing Authorization header\"}", arena);
    return resp;
  }

  const char *auth_header = ((Seobeo_Request_Entry*)auth_kv)->value;
  if (strncmp(auth_header, "Bearer ", 7) != 0)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "401", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Invalid Authorization format\"}", arena);
    return resp;
  }

  const char *token = auth_header + 7;
  if (strlen(g_upload_auth_token) == 0 || strcmp(token, g_upload_auth_token) != 0)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "403", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Invalid token\"}", arena);
    return resp;
  }

  if (!g_db_connection)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Database not available\"}", arena);
    return resp;
  }

  // Extract media_id from URL params
  void *id_kv = Dowa_HashMap_Get_Ptr(req, ":id");
  if (!id_kv)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "400", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Missing media ID\"}", arena);
    return resp;
  }

  const char *media_id_str = ((Seobeo_Request_Entry*)id_kv)->value;
  int64 media_id = atoll(media_id_str);

  // Verify access_token matches and get content_type
  const char *select_query =
    "SELECT content_type, s3_key_original, s3_key_processed FROM media_uploads WHERE id = ? AND access_token = ?";
  const char *select_params[] = { media_id_str, token };

  Deita_Result_Set *p_result = Deita_Query_Execute_Prepared(g_db_connection, select_query, 2, select_params, arena);

  if (!p_result || !Deita_Result_Set_Next(p_result))
  {
    if (p_result) Deita_Result_Set_Free(p_result);
    Dowa_HashMap_Push_Arena(resp, "status", "404", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Media not found or access denied\"}", arena);
    return resp;
  }

  const char *content_type = Deita_Result_Set_Get_Text(p_result, 0);
  const char *s3_key_original = Deita_Result_Set_Get_Text(p_result, 1);
  const char *s3_key_processed = Deita_Result_Set_Get_Text(p_result, 2);

  // Copy values before freeing result set
  char content_type_copy[128];
  char s3_key_original_copy[512];
  char s3_key_processed_copy[512];
  strncpy(content_type_copy, content_type, sizeof(content_type_copy) - 1);
  strncpy(s3_key_original_copy, s3_key_original, sizeof(s3_key_original_copy) - 1);
  strncpy(s3_key_processed_copy, s3_key_processed, sizeof(s3_key_processed_copy) - 1);
  content_type_copy[sizeof(content_type_copy) - 1] = '\0';
  s3_key_original_copy[sizeof(s3_key_original_copy) - 1] = '\0';
  s3_key_processed_copy[sizeof(s3_key_processed_copy) - 1] = '\0';

  Deita_Result_Set_Free(p_result);

  // Update status to 'uploaded'
  const char *update_query =
    "UPDATE media_uploads SET status='uploaded', updated_at=strftime('%s','now') WHERE id=?";
  const char *update_params[] = { media_id_str };
  int32 result = Deita_Query_Execute_Update_Prepared(g_db_connection, update_query, 1, update_params);

  if (result < 0)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Failed to update status\"}", arena);
    return resp;
  }

  Seobeo_Log(SEOBEO_INFO, "[MEDIA] Content type for media_id=%lld: '%s'\n", (long long)media_id, content_type_copy);

  // Images are processed asynchronously by the bounded media pool.
  if (strncmp(content_type_copy, "image/", 6) == 0)
  {
    Seobeo_Log(SEOBEO_INFO, "[MEDIA] Queueing image processing for media_id=%lld\n", (long long)media_id);

    // The pool owns this context after a successful submission.
    Media_Processing_Context *ctx = malloc(sizeof(Media_Processing_Context));
    if (!ctx)
    {
      Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
      Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
      Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Unable to allocate media work\"}", arena);
      return resp;
    }
    ctx->media_id = media_id;
    strncpy(ctx->s3_key_original, s3_key_original_copy, sizeof(ctx->s3_key_original) - 1);
    strncpy(ctx->s3_key_processed, s3_key_processed_copy, sizeof(ctx->s3_key_processed) - 1);
    strncpy(ctx->content_type, content_type_copy, sizeof(ctx->content_type) - 1);
    strncpy(ctx->access_token, token, sizeof(ctx->access_token) - 1);
    strncpy(ctx->db_path, g_db_path, sizeof(ctx->db_path) - 1);
    ctx->s3_key_original[sizeof(ctx->s3_key_original) - 1] = '\0';
    ctx->s3_key_processed[sizeof(ctx->s3_key_processed) - 1] = '\0';
    ctx->content_type[sizeof(ctx->content_type) - 1] = '\0';
    ctx->access_token[sizeof(ctx->access_token) - 1] = '\0';
    ctx->db_path[sizeof(ctx->db_path) - 1] = '\0';
    ctx->s3_config = g_s3_config;

    Seobeo_Worker_Result worker_result =
        g_media_worker_pool
            ? Seobeo_Worker_Pool_Submit(
                g_media_worker_pool,
                Media_Process_Background,
                ctx,
                free)
            : SEOBEO_WORKER_STOPPED;
    if (worker_result != SEOBEO_WORKER_OK)
    {
      Seobeo_Log(
          SEOBEO_ERROR,
          "[MEDIA] Worker submission failed with result=%d for media_id=%lld\n",
          worker_result,
          (long long)media_id);
      free(ctx);
      const char *update_error =
        "UPDATE media_uploads SET status='error', error_message=?, updated_at=strftime('%s','now') WHERE id=?";
      const char *error_params[] = {
        "Media worker queue is unavailable",
        media_id_str,
      };
      Deita_Query_Execute_Update_Prepared(
          g_db_connection,
          update_error,
          2,
          error_params);
      Dowa_HashMap_Push_Arena(resp, "status", "503", arena);
      Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
      Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Media worker queue is unavailable\"}", arena);
      return resp;
    }
    Seobeo_Log(
        SEOBEO_INFO,
        "[MEDIA] Submitted media_id=%lld to the worker pool\n",
        (long long)media_id);
  }
  else
  {
    Seobeo_Log(SEOBEO_INFO, "[MEDIA] Non-image file, skipping background processing for media_id=%lld\n", (long long)media_id);
  }

  Dowa_HashMap_Push_Arena(resp, "status", "200", arena);
  Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
  Dowa_HashMap_Push_Arena(resp, "body", "{\"success\":true,\"status\":\"uploaded\"}", arena);

  Seobeo_Log(SEOBEO_INFO, "[MEDIA] Marked uploaded media_id=%lld\n", (long long)media_id);

  return resp;
}

// Media Upload API - Get status
// GET /api/media/:id/status
// Headers: Authorization: Bearer <token>
// Returns: {"id": 123, "status": "finished", "processed_url": "https://...", "error_message": null}
Seobeo_Request_Entry *MediaStatus(Seobeo_Request_Entry *req, Dowa_Arena *arena)
{
  Seobeo_Request_Entry *resp = NULL;

  // Check auth token
  void *auth_kv = Dowa_HashMap_Get_Ptr(req, "Authorization");
  if (!auth_kv)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "401", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Missing Authorization header\"}", arena);
    return resp;
  }

  const char *auth_header = ((Seobeo_Request_Entry*)auth_kv)->value;
  if (strncmp(auth_header, "Bearer ", 7) != 0)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "401", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Invalid Authorization format\"}", arena);
    return resp;
  }

  const char *token = auth_header + 7;
  if (strlen(g_upload_auth_token) == 0 || strcmp(token, g_upload_auth_token) != 0)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "403", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Invalid token\"}", arena);
    return resp;
  }

  if (!g_db_connection)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "500", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Database not available\"}", arena);
    return resp;
  }

  // Extract media_id from URL params
  void *id_kv = Dowa_HashMap_Get_Ptr(req, ":id");
  if (!id_kv)
  {
    Dowa_HashMap_Push_Arena(resp, "status", "400", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Missing media ID\"}", arena);
    return resp;
  }

  const char *media_id_str = ((Seobeo_Request_Entry*)id_kv)->value;

  // Query media status
  const char *select_query =
    "SELECT id, status, s3_key_original, s3_key_processed, error_message FROM media_uploads WHERE id = ? AND access_token = ?";
  const char *select_params[] = { media_id_str, token };

  Deita_Result_Set *p_result = Deita_Query_Execute_Prepared(g_db_connection, select_query, 2, select_params, arena);

  if (!p_result || !Deita_Result_Set_Next(p_result))
  {
    if (p_result) Deita_Result_Set_Free(p_result);
    Dowa_HashMap_Push_Arena(resp, "status", "404", arena);
    Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
    Dowa_HashMap_Push_Arena(resp, "body", "{\"error\":\"Media not found\"}", arena);
    return resp;
  }

  int64 id = Deita_Result_Set_Get_Integer(p_result, 0);
  const char *status = Deita_Result_Set_Get_Text(p_result, 1);
  const char *s3_key_original = Deita_Result_Set_Get_Text(p_result, 2);
  const char *s3_key_processed = Deita_Result_Set_Get_Text(p_result, 3);
  const char *error_message = Deita_Result_Set_Get_Text(p_result, 4);

  // Build CloudFront URL for processed file if status is 'finished'
  char processed_url[1024] = {0};
  if (strcmp(status, "finished") == 0 && s3_key_processed && strlen(s3_key_processed) > 0)
  {
    if (g_s3_cloudfront_url[0])
    {
      snprintf(processed_url, sizeof(processed_url), "%s/%s", g_s3_cloudfront_url, s3_key_processed);
    }
    else
    {
      snprintf(processed_url, sizeof(processed_url), "https://%s.s3.%s.amazonaws.com/%s",
               g_s3_bucket, g_s3_region, s3_key_processed);
    }
  }

  // Build CloudFront URL for original file (for non-images or before processing completes)
  char original_url[1024] = {0};
  if (s3_key_original && strlen(s3_key_original) > 0)
  {
    if (g_s3_cloudfront_url[0])
    {
      snprintf(original_url, sizeof(original_url), "%s/%s", g_s3_cloudfront_url, s3_key_original);
    }
    else
    {
      snprintf(original_url, sizeof(original_url), "https://%s.s3.%s.amazonaws.com/%s",
               g_s3_bucket, g_s3_region, s3_key_original);
    }
  }

  // Build JSON response with both processed_url and original_url
  char *response_body = Dowa_Arena_Allocate(arena, 3072);

  // Build the base response
  int offset = snprintf(response_body, 3072,
                        "{\"id\":%lld,\"status\":\"%s\",",
                        (long long)id, status);

  // Add processed_url
  if (strlen(processed_url) > 0)
  {
    offset += snprintf(response_body + offset, 3072 - offset,
                       "\"processed_url\":\"%s\",", processed_url);
  }
  else
  {
    offset += snprintf(response_body + offset, 3072 - offset,
                       "\"processed_url\":null,");
  }

  // Add original_url
  if (strlen(original_url) > 0)
  {
    offset += snprintf(response_body + offset, 3072 - offset,
                       "\"original_url\":\"%s\",", original_url);
  }
  else
  {
    offset += snprintf(response_body + offset, 3072 - offset,
                       "\"original_url\":null,");
  }

  // Add error_message
  if (error_message && strlen(error_message) > 0)
  {
    snprintf(response_body + offset, 3072 - offset,
             "\"error_message\":\"%s\"}", error_message);
  }
  else
  {
    snprintf(response_body + offset, 3072 - offset,
             "\"error_message\":null}");
  }

  Deita_Result_Set_Free(p_result);

  Dowa_HashMap_Push_Arena(resp, "status", "200", arena);
  Dowa_HashMap_Push_Arena(resp, "content-type", "application/json", arena);
  Dowa_HashMap_Push_Arena(resp, "body", response_body, arena);

  return resp;
}

int main(void)
{
  signal(SIGINT, handle_sigint);
  signal(SIGTERM, handle_sigint);

  // Load the ignored runtime config when present; environment overrides follow.
  const char *config_path = getenv("MRJUNEJUNE_CONFIG_PATH");
  load_config(
      config_path && config_path[0] != '\0'
          ? config_path
          : "mrjunejune/.config");

  // Initialize S3 config using global credentials populated by load_config
  g_s3_config.access_key_id = g_s3_access_key;
  g_s3_config.secret_access_key = g_s3_secret_key;
  g_s3_config.region = g_s3_region;
  g_s3_config.bucket = g_s3_bucket;
  g_s3_config.endpoint = NULL;
  g_s3_config.use_path_style = FALSE;

  printf("[S3] Configured: region=%s, bucket=%s, key=%s...\n",
         g_s3_region, g_s3_bucket, g_s3_access_key[0] ? "***" : "(missing)");

  // Show current working directory
  char cwd[1024];
  if (getcwd(cwd, sizeof(cwd)) != NULL)
  {
    printf("[STARTUP] Current working directory: %s\n", cwd);
    printf("[STARTUP] Database path (relative): %s\n", g_db_path);
  }

  // Initialize database
  init_database();
  {
    /* Validate per-request token cap against daily limit now that both
     * are finalised (env overrides run inside load_config). */
    if (g_guest_request_output_tokens > g_guest_daily_output_tokens)
      g_guest_request_output_tokens = g_guest_daily_output_tokens;

    Conversation_API_Guest_Policy policy = {
      .guest_inference_enabled = g_guest_inference_enabled,
      .daily_turns             = g_guest_daily_turns,
      .daily_output_tokens     = g_guest_daily_output_tokens,
      .request_output_tokens   = g_guest_request_output_tokens,
    };
    if (!Conversation_API_Init(g_db_path, &policy))
      Seobeo_Log(SEOBEO_ERROR, "[CONVERSATION] Store unavailable\n");
  }

  /* Validate and decode AUTH_COOKIE_SECRET: hex string → raw bytes. */
  uint8  cookie_secret_bytes[AUTH_CRYPTO_COOKIE_SECRET_MAX_BYTES];
  size_t cookie_secret_byte_len = 0;
  {
    size_t hex_len = strlen(g_auth_cookie_secret);
    boolean bad_len = (
        hex_len < (size_t)(AUTH_CRYPTO_COOKIE_SECRET_MIN_BYTES * 2) ||
        hex_len > (size_t)(AUTH_CRYPTO_COOKIE_SECRET_MAX_BYTES * 2) ||
        hex_len % 2 != 0);
    if (bad_len)
    {
      OPENSSL_cleanse(g_auth_cookie_secret, sizeof(g_auth_cookie_secret));
      fprintf(stderr,
              "[AUTH] AUTH_COOKIE_SECRET must be %d–%d hex chars "
              "(%d–%d random bytes). "
              "Generate with: openssl rand -hex 32\n",
              AUTH_CRYPTO_COOKIE_SECRET_MIN_BYTES * 2,
              AUTH_CRYPTO_COOKIE_SECRET_MAX_BYTES * 2,
              AUTH_CRYPTO_COOKIE_SECRET_MIN_BYTES,
              AUTH_CRYPTO_COOKIE_SECRET_MAX_BYTES);
      exit(1);
    }
    cookie_secret_byte_len = config__hex_decode(
        g_auth_cookie_secret, cookie_secret_bytes, sizeof(cookie_secret_bytes));
    OPENSSL_cleanse(g_auth_cookie_secret, sizeof(g_auth_cookie_secret));
    if (cookie_secret_byte_len < (size_t)AUTH_CRYPTO_COOKIE_SECRET_MIN_BYTES)
    {
      OPENSSL_cleanse(cookie_secret_bytes, sizeof(cookie_secret_bytes));
      fprintf(stderr,
              "[AUTH] AUTH_COOKIE_SECRET contains non-hex characters or "
              "is too short.\n");
      exit(1);
    }
  }

  /* Bootstrap pairing: both username+hash must be set, or both absent. */
  {
    boolean has_user = g_auth_bootstrap_username[0] != '\0';
    boolean has_hash = g_auth_bootstrap_password_hash[0] != '\0';
    if (has_user != has_hash)
    {
      OPENSSL_cleanse(cookie_secret_bytes, sizeof(cookie_secret_bytes));
      fprintf(stderr,
              "[AUTH] AUTH_BOOTSTRAP_USERNAME and AUTH_BOOTSTRAP_PASSWORD_HASH "
              "must both be set or both absent.\n");
      exit(1);
    }
    if (has_hash &&
        Auth_Crypto_Password_Hash_Validate(g_auth_bootstrap_password_hash) != AUTH_CRYPTO_OK)
    {
      OPENSSL_cleanse(cookie_secret_bytes, sizeof(cookie_secret_bytes));
      fprintf(stderr,
              "[AUTH] AUTH_BOOTSTRAP_PASSWORD_HASH has unrecognized format "
              "(expected zenbu-scrypt$v=1$...).\n");
      exit(1);
    }
  }

  /* TTL validation: all positive, idle <= abs, all within 1 min – 1 year. */
#define CONFIG_TTL_MIN_SECS 60
#define CONFIG_TTL_MAX_SECS 31536000
  {
    int64 idle  = g_auth_session_idle_ttl;
    int64 abst  = g_auth_session_abs_ttl;
    int64 guest = g_auth_guest_ttl;
    if (idle <= 0 || abst <= 0 || guest <= 0 ||
        idle < CONFIG_TTL_MIN_SECS || idle > CONFIG_TTL_MAX_SECS ||
        abst < CONFIG_TTL_MIN_SECS || abst > CONFIG_TTL_MAX_SECS ||
        guest < CONFIG_TTL_MIN_SECS || guest > CONFIG_TTL_MAX_SECS)
    {
      OPENSSL_cleanse(cookie_secret_bytes, sizeof(cookie_secret_bytes));
      fprintf(stderr,
              "[AUTH] TTL values must be %d–%d seconds.\n",
              CONFIG_TTL_MIN_SECS, CONFIG_TTL_MAX_SECS);
      exit(1);
    }
    if (idle > abst)
    {
      OPENSSL_cleanse(cookie_secret_bytes, sizeof(cookie_secret_bytes));
      fprintf(stderr,
              "[AUTH] AUTH_SESSION_IDLE_TTL must not exceed "
              "AUTH_SESSION_ABS_TTL.\n");
      exit(1);
    }
  }

  /* Trusted proxy: validate and canonicalize via inet_pton/inet_ntop. */
  if (g_auth_trusted_proxy[0] != '\0')
  {
    struct in_addr  addr4;
    struct in6_addr addr6;
    char canonical[AUTH_CRYPTO_IP_MAX_BYTES];
    canonical[0] = '\0';
    if (inet_pton(AF_INET, g_auth_trusted_proxy, &addr4) == 1)
    {
      if (!inet_ntop(AF_INET, &addr4, canonical, sizeof(canonical)))
      {
        OPENSSL_cleanse(cookie_secret_bytes, sizeof(cookie_secret_bytes));
        fprintf(stderr,
                "[AUTH] AUTH_TRUSTED_PROXY: IPv4 canonicalization failed.\n");
        exit(1);
      }
    }
    else if (inet_pton(AF_INET6, g_auth_trusted_proxy, &addr6) == 1)
    {
      if (!inet_ntop(AF_INET6, &addr6, canonical, sizeof(canonical)))
      {
        OPENSSL_cleanse(cookie_secret_bytes, sizeof(cookie_secret_bytes));
        fprintf(stderr,
                "[AUTH] AUTH_TRUSTED_PROXY: IPv6 canonicalization failed.\n");
        exit(1);
      }
    }
    else
    {
      OPENSSL_cleanse(cookie_secret_bytes, sizeof(cookie_secret_bytes));
      fprintf(stderr,
              "[AUTH] AUTH_TRUSTED_PROXY must be a valid IPv4 or IPv6 "
              "address (e.g. 192.168.1.1 or ::1).\n");
      exit(1);
    }
    strncpy(g_auth_trusted_proxy, canonical, sizeof(g_auth_trusted_proxy) - 1);
    g_auth_trusted_proxy[sizeof(g_auth_trusted_proxy) - 1] = '\0';
  }

  /*
   * Loopback enforcement: AUTH_DEV_INSECURE_COOKIE=true is only permitted
   * when SERVER_HOST is explicitly a loopback address.  Production/edge
   * deployments must use Secure cookies.
   */
  {
    boolean is_loopback = (
        strcmp(g_server_host, "127.0.0.1") == 0 ||
        strcmp(g_server_host, "::1")        == 0 ||
        strcmp(g_server_host, "localhost")   == 0);
    if (g_auth_dev_insecure && !is_loopback)
    {
      OPENSSL_cleanse(cookie_secret_bytes, sizeof(cookie_secret_bytes));
      fprintf(stderr,
              "[AUTH] AUTH_DEV_INSECURE_COOKIE=true requires SERVER_HOST "
              "to be a loopback address (127.0.0.1, ::1, or localhost). "
              "Set SERVER_HOST=127.0.0.1 for local development.\n");
      exit(1);
    }
  }

  /* Initialize auth module — fail closed: no auth means no server. */
  {
    if (!Auth_API_Init(
            g_db_path,
            cookie_secret_bytes, cookie_secret_byte_len,
            g_auth_bootstrap_username[0] ? g_auth_bootstrap_username : NULL,
            g_auth_bootstrap_password_hash[0] ? g_auth_bootstrap_password_hash : NULL,
            g_auth_trusted_proxy[0] ? g_auth_trusted_proxy : NULL,
            g_auth_session_idle_ttl,
            g_auth_session_abs_ttl,
            g_auth_guest_ttl,
            g_auth_dev_insecure))
    {
      OPENSSL_cleanse(cookie_secret_bytes, sizeof(cookie_secret_bytes));
      fprintf(stderr,
              "[AUTH] Auth init failed — refusing to start server.\n");
      exit(1);
    }
    OPENSSL_cleanse(cookie_secret_bytes, sizeof(cookie_secret_bytes));
  }
  const char *sidecar_path = getenv("MRJUNEJUNE_INFERENCE_SIDECAR_PATH");
  const char *copilot_cli_path = getenv("MRJUNEJUNE_COPILOT_CLI_PATH");
  if (sidecar_path && copilot_cli_path)
  {
    if (!Conversation_API_Enable_Inference(sidecar_path, copilot_cli_path))
      Seobeo_Log(SEOBEO_ERROR, "[INFERENCE] Sidecar unavailable\n");
  }
  else
  {
    Seobeo_Log(
        SEOBEO_WARNING,
        "[INFERENCE] Runtime paths not configured; turns return 503\n");
  }

  g_media_worker_pool = Seobeo_Worker_Pool_Create(2, 16);
  if (!g_media_worker_pool)
  {
    Seobeo_Log(
        SEOBEO_ERROR,
        "[MEDIA] Unable to initialize the media worker pool\n");
  }

  Seobeo_Router_Init();
  Auth_API_Register_Routes();
  Admin_API_Register_Routes();
  Conversation_API_Register_Routes();

  Seobeo_Router_Register("GET", "/", GetHomePage);
  Seobeo_Router_Register("GET", "/index.html", GetRedirectHomePage);

  Seobeo_Router_Register("GET", "/resume", GetResume);
  Seobeo_Router_Register("GET", "/resume/index.html", GetRedirectResume);

  Seobeo_Router_Register("GET", "/tools", GetTools);
  Seobeo_Router_Register("GET", "/tools/index.html", GetRedirectTools);

  Seobeo_Router_Register("GET", "/tools/markdown_to_html", GetMDToHTML);
  Seobeo_Router_Register("GET", "/tools/markdown_to_html/index.html", GetRedirectMarkDownToHtml);

  Seobeo_Router_Register("GET", "/tools/file_converter", GetFileConverter);
  Seobeo_Router_Register("GET", "/tools/file_converter/index.html", GetRedirectFileConverter);
  Seobeo_Router_Register("GET", "/tools/hls_player", GetHlsPlayer);
  Seobeo_Router_Register("GET", "/tools/hls_player/index.html", GetRedirectHlsPlayer);
  Seobeo_Router_Register("GET", "/tools/latex_editor", GetLatexEditor);
  Seobeo_Router_Register("GET", "/tools/latex_editor/index.html", GetRedirectLatexEditor);

  // -- File converter --/
  Seobeo_Router_Register("POST", "/api/convert/image-to-webp", ConvertImageToWebP);
  Seobeo_Router_Register("POST", "/api/convert/video-to-mp4", ConvertVideoToMP4);
  Seobeo_Router_Register("GET", "/api/download/:filename", DownloadConvertedFile);
  Seobeo_Router_Register("DELETE", "/api/download/:filename", DeleteConvertedFile);
  Seobeo_Router_Register("POST", "/api/latex/render", RenderLatexPdf);

  // -- S3 Upload --/
  Seobeo_Router_Register("POST", "/api/s3/upload-url", GetS3UploadUrl);

  // -- Media Upload --/
  Seobeo_Router_Register("POST", "/api/media/create", MediaCreate);
  Seobeo_Router_Register("POST", "/api/media/:id/uploaded", MediaUploaded);
  Seobeo_Router_Register("GET", "/api/media/:id/status", MediaStatus);

  // -- Editor --/
  Seobeo_Router_Register("POST", "/api/editor/save", EditorSave);
  Seobeo_Router_Register("GET", "/api/editor/load/:doc_id", EditorLoad);

  // -- Blog --/
  Seobeo_Router_Register("GET", "/blog", RenderBlogList);
  Seobeo_Router_Register("GET", "/blog/:blog_id", RenderBlog);

  // -- Talk --/
  Seobeo_Router_Register("GET", "/talk", GetTalk);
  Seobeo_Router_Register("GET", "/talk/index.html", GetRedirectTalk);

  // -- JRPG agent chat --/
  Seobeo_Router_Register("GET", "/jrpg", GetJrpg);
  Seobeo_Router_Register("GET", "/jrpg/index.html", GetRedirectJrpg);

  // -- Login --/
  Seobeo_Router_Register("GET", "/login", GetLogin);

  // -- Notes --/
  Seobeo_Router_Register("GET", "/notes", GetNotes);
  Seobeo_Router_Register("GET", "/notes/", GetNotes);
  Seobeo_Router_Register("GET", "/notes/index.html", GetNotes);
  Seobeo_Router_Register("GET", "/notes/login", GetNotesLogin);
  Seobeo_Router_Register("GET", "/notes/login/", GetNotesLogin);
  Seobeo_Router_Register("GET", "/notes/:note_id", GetNoteById);

  Seobeo_WebSocket_Server_Init();
  Seobeo_WebSocket_Server_Register("/chat", Chat_Handler, NULL);

  Seobeo_Log(SEOBEO_INFO, "WTF is going on\n");
  const char *server_port = getenv("MRJUNEJUNE_PORT");
  if (!server_port || server_port[0] == '\0')
    server_port = "6969";
  const char *server_bind = g_server_host[0] ? g_server_host : "0.0.0.0";
  Mjj_Template_Renderer_Init("mrjunejune/src");
  int server_result = Seobeo_Web_Server_Start_On(
      server_bind, "mrjunejune/src", server_port, SEOBEO_MODE_EDGE, 4);
  Seobeo_Worker_Pool_Destroy(g_media_worker_pool);
  g_media_worker_pool = NULL;
  Conversation_API_Destroy();
  Auth_API_Destroy();
  if (server_result != 0)
  {
    fprintf(stderr, "[STARTUP] Server bind/listen failed (host=%s port=%s)\n",
            server_bind, server_port);
    return 1;
  }
  return 0;
}