#ifndef DOWA
#define DOWA

#include <stdio.h>
#include <string.h> // stdup
#include <stdlib.h> // only for malloc, free, stuff
#include <assert.h>
#include <dirent.h>

#include <sys/stat.h>
#include <limits.h>

#include "dowa_internal.h"

#define HASH_KEY_NUMBER 5381 // DJD hash number
#define ONE_MEGA_BYTE   1048576
#define TRUE  1
#define FALSE 0

typedef unsigned int uint32;
typedef int int32;
typedef unsigned short uint16;
typedef short int16;
typedef unsigned char uint8;
typedef char int8;
typedef char boolean;

// --- Misc --- //
char *Dowa_Int32ToString(uint32 int32, char *buffer);

// --- Arena --- //
typedef struct {
  char   *buffer;
  size_t offset;
  size_t capacity;
} Dowa_Arena, *Dowa_PArena;

extern Dowa_PArena Dowa_Arena_Create(size_t capacity);
extern void        *Dowa_Arena_Allocate(Dowa_PArena p_arena, size_t size);
extern void        Dowa_Arena_Free(Dowa_PArena p_arena);

// --- HashMap --- //
typedef enum {
  DOWA_HASH_MAP_TYPE_BUFFER,
  DOWA_HASH_MAP_TYPE_STRING,
  DOWA_HASH_MAP_TYPE_HASHMAP,
  DOWA_HASH_MAP_TYPE_INT,
} Dowa_HashMap_ValueType;

typedef struct {
  char           *key;
  void           *buffer; 
  size_t         capacity;
  Dowa_HashMap_ValueType type;
} Dowa_HashEntry, *Dowa_PHashEntry;

typedef struct {
  Dowa_PHashEntry *entries;
  size_t          capacity;
  uint32          current_capacity;
} Dowa_HashMap, *Dowa_PHashMap;

extern Dowa_PHashMap   Dowa_HashMap_Create(size_t capacity);
extern void            Dowa_HashMap_Free(Dowa_PHashMap p_hash_map);
extern int32           Dowa_HashMap_GetPosition(Dowa_PHashMap p_hash_map, char *key);
extern void            *Dowa_HashMap_Get(Dowa_PHashMap p_hash_map, char *key);
extern void            Dowa_HashMap_PushValue(Dowa_PHashMap p_hash_map, char *key, void *value, size_t value_size);
extern int32           Dowa_HashMap_PushValueWithTypeNoCopy(Dowa_PHashMap p_hash_map, char *key, void *value, size_t value_size, Dowa_HashMap_ValueType type);
extern int32           Dowa_HashMap_PushValueWithType(Dowa_PHashMap p_hash_map, char *key, void *value, size_t value_size, Dowa_HashMap_ValueType type);
extern void            Dowa_HashMap_PopKey(Dowa_PHashMap p_hash_map, char *key);

// --- Maybe Useful --- //
extern void Dowa_HashMap_Print(Dowa_PHashMap map);
// 0 for success, -1 for failure. Get all files in the folder into key and vlaues.
extern int  Dowa_HashMap_Cache_Folder(Dowa_PHashMap map, const char *folder_path);


#endif
