#ifndef LIB_CTL_H
#define LIB_CTL_H

#include <libhttp.h>
#include <libstr.h>

typedef struct ctl_ctx ctl_ctx_t;
typedef void (*ctl_fn_t)(char **ctl_out, ctl_ctx_t ctx);

struct ctl_ctx {
  http_req_t *request;
  char *title;
  ctl_fn_t fn;
  void *data;
};

void ctl_init(ctl_fn_t fn);
http_resp_t ctl_serve_page(http_req_t *request, const char *title, ctl_fn_t fn, void *data);
http_resp_t ctl_serve_component(http_req_t *request, ctl_fn_t fn, void *data);

#ifdef LIB_CTL_IMPL

static ctl_fn_t ctl_fn = NULL;

void ctl_init(ctl_fn_t fn) {
  ctl_fn = fn;
}

http_resp_t ctl_serve_page(http_req_t *request, const char *title, ctl_fn_t fn, void *data) {
  char *html = NULL;
  ctl_ctx_t ctx = {
    .request = request,
    .title = title,
    .fn = fn,
    .data = data,
  };
  ctl_fn(&html, ctx);
  http_resp_t response = http_resp_create(HTTP_STATUS_OK);
  http_header_set(&response, "Content-Type", "text/html");
  http_resp_body_set(&response, html, strlen(html));
  free(html);
  return response;
}

http_resp_t ctl_serve_component(http_req_t *request, ctl_fn_t fn, void *data) {
  char *html = NULL;
  ctl_ctx_t ctx = {
    .request = request,
    .data = data,
  };
  fn(&html, ctx);
  http_resp_t response = http_resp_create(HTTP_STATUS_OK);
  http_header_set(&response, "Content-Type", "text/html");
  http_resp_body_set(&response, html, strlen(html));
  free(html);
  return response;
}

#endif /* LIB_CTL_IMPL */
#endif /* LIB_CTL_H */
