#include "seobeo/seobeo.h"

#include <stdlib.h>
#include <string.h>

static Seobeo_Request_Entry *Get_Component_Catalog(
    Seobeo_Request_Entry *request,
    Dowa_Arena *arena)
{
  (void)request;
  size_t file_size = 0;
  char *source = Seobeo_Web_LoadFile("/index.html", &file_size);
  if (!source)
  {
    Seobeo_Request_Entry *response = NULL;
    Dowa_HashMap_Push_Arena(response, "status", "500", arena);
    Dowa_HashMap_Push_Arena(
        response,
        "content-type",
        "text/plain; charset=utf-8",
        arena);
    Dowa_HashMap_Push_Arena(
        response,
        "body",
        "Component catalog is unavailable.",
        arena);
    return response;
  }

  char *body = Dowa_Arena_Allocate(arena, file_size + 1);
  if (!body)
  {
    free(source);
    return NULL;
  }
  memcpy(body, source, file_size + 1);
  free(source);

  char *content_length = Dowa_Arena_Allocate(arena, 32);
  snprintf(content_length, 32, "%zu", file_size);
  Seobeo_Request_Entry *response = NULL;
  Dowa_HashMap_Push_Arena(response, "status", "200", arena);
  Dowa_HashMap_Push_Arena(
      response,
      "content-type",
      "text/html; charset=utf-8",
      arena);
  Dowa_HashMap_Push_Arena(
      response,
      "content-length",
      content_length,
      arena);
  Dowa_HashMap_Push_Arena(response, "body", body, arena);
  return response;
}

static boolean Port_Is_Valid(const char *port)
{
  if (!port || port[0] == '\0')
    return FALSE;
  char *end = NULL;
  long value = strtol(port, &end, 10);
  return end != port &&
      *end == '\0' &&
      value > 0 &&
      value <= 65535;
}

int main(void)
{
  Seobeo_Router_Init();
  Seobeo_Router_Register("GET", "/", Get_Component_Catalog);
  Seobeo_Router_Register("GET", "/tokens", Get_Component_Catalog);
  Seobeo_Router_Register("GET", "/components", Get_Component_Catalog);
  Seobeo_Router_Register("GET", "/components/button", Get_Component_Catalog);
  Seobeo_Router_Register("GET", "/components/card", Get_Component_Catalog);
  Seobeo_Router_Register("GET", "/components/alert", Get_Component_Catalog);
  Seobeo_Router_Register("GET", "/components/field", Get_Component_Catalog);
  Seobeo_Router_Register("GET", "/components/stack", Get_Component_Catalog);

  const char *port = getenv("DESIGN_SYSTEM_PORT");
  if (!port || port[0] == '\0')
    port = "6980";
  if (!Port_Is_Valid(port))
  {
    Seobeo_Log(SEOBEO_ERROR, "Invalid design-system port: %s\n", port);
    Seobeo_Router_Destroy();
    return 1;
  }
  int result = Seobeo_Web_Server_Start_On(
      "127.0.0.1",
      "design_system/src",
      port,
      SEOBEO_MODE_EDGE,
      2);
  Seobeo_Router_Destroy();
  return result;
}
