#ifndef SEOBEO_SERVER_H
#define SEOBEO_SERVER_H

// --- Seobeo --- //
// Library for creating sockets, binding sockets, and listening to a sockets.
// Sending and unpacking bytes of data. 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdatomic.h>
#include <stdbool.h>

#include "dowa/dowa.h"

#define INITIAL_BUFFER_CAPACITY 4096

// HTTP STATUS CODE
#define HTTP_OK 200
#define HTTP_CREATED 201
#define HTTP_MOVED_PERMANENTLY 301
#define HTTP_FOUND 302
#define HTTP_BAD_REQUEST 400
#define HTTP_UNAUTHORIZED 401
#define HTTP_FORBIDDEN 403
#define HTTP_NOT_FOUND 404
#define HTTP_INTERNAL_ERROR 500

typedef struct {
  int     socket; 
  char    *host;
  char    *port;

  uint8   *read_buffer;
  uint32  read_buffer_capacity;
  uint32  read_buffer_len; // current size
  uint32  read_buffer_used; // TODO: Implement this for client 

  uint8   *write_buffer;
  uint32  write_buffer_capacity;
  uint32  write_buffer_len; // current size

  void    *file;
  void    *text_copy;
  char    *file_name;

  atomic_bool destroyed;
} Sebeo_Handle, *Seobeo_PHandle;

typedef struct {
  Seobeo_PHandle  srv;
  Dowa_PHashMap   cache;
  int             evfd;    // epoll‐fd or kqueue‐fd
} WorkerArgs;

typedef enum {
  SEOBEO_MODE_FORK,
  SEOBEO_MODE_EDGE,
} Seobeo_ServerMode;

// --- Socket, IP related --- //
extern int            Seobeo_CreateSocket(int32 stream, const char *host,  const char* port);
extern void           *Seobeo_GetIP4OrIP6(struct sockaddr *sa);

// --- TCP --- //
extern Seobeo_PHandle Seobeo_Stream_Handle_Create(const char *host,  const char* port);
extern Seobeo_PHandle Seobeo_Stream_Handle_Accept(Seobeo_PHandle p_server_handle);
extern int            Seobeo_Stream_Handle_Read(Seobeo_PHandle p_handle);

// --- Web --- //
extern void           Seobeo_Web_GenerateResponseHeader(void *buffer, int status, const char *content_type, const int content_length);
extern void           Seobeo_Web_HandleClientRequest(Seobeo_PHandle cli, Dowa_PHashMap p_html_cache);
extern int            Seobeo_Web_ParseClientHeader(Seobeo_PHandle p_handle, Dowa_PHashMap map);
extern int            Seobeo_Web_StartBasicHTTPServer(const char *folder_path, const char *port, Seobeo_ServerMode mode, int thread_count);
extern void           *Seobeo_Web_Edge_Worker(void *vargs); // Maybe not web only...
extern void           Seobeo_Web_Edge(Seobeo_PHandle p_server_handle, int thread_count, Dowa_PHashMap p_html_cache);
extern int            Seobeo_Web_ClientGet(const char *host, const char *port, const char *path);


// --- Helper functions --- //
extern void           Seobeo_Handle_Destroy(Seobeo_PHandle p_handle);
extern int            Seobeo_Handle_Flush(Seobeo_PHandle p_handle);
extern int            Seobeo_Handle_Queue(Seobeo_PHandle p_handle, const uint8_t *data, uint32_t data_size);
extern int            Seobeo_Handle_Read(Seobeo_PHandle p_handle);
extern void           Seobeo_Handle_Consume(Seobeo_PHandle p_handle, uint32 consumed);


#endif
