#ifndef JSON_ENTITIES_H
#define JSON_ENTITIES_H

#include "aliases.h"
#include "dstring.h"
#include <stdbool.h>

typedef struct json_entity jentity_t;
typedef struct json_collection jcoll_t;
typedef struct json_value jval_t;
typedef struct json_pair jpair_t;

typedef enum {
  JVAL_EMPTY,
  JVAL_COLLECTION,
  JVAL_STRING,
  JVAL_INTEGER,
  JVAL_DOUBLE,
  JVAL_BOOLEAN,
  JVAL_NULL,
} jval_type;

struct json_value {
  jval_type type;
  union {
    void *null_val;
    jcoll_t *collection;
    dstr_t *string;
    i64 num_int;
    f64 num_dbl;
    bool boolean;
  };
};

struct json_pair {
  dstr_t *key;
  jval_t value;
};

typedef enum {
  JENTITY_SINGLE,
  JENTITY_PAIR,
} jentity_type;

struct json_entity {
  jentity_type type;
  union {
    jval_t value;
    jpair_t pair;
  };
  jentity_t *parent;
  jentity_t *next;
};

typedef enum {
  JCOLL_OBJECT,
  JCOLL_ARRAY,
} jcoll_type;

struct json_collection {
  u64 size;
  jcoll_type type;
  jentity_t *begin;
  jentity_t *end;
};

void print_json(const jentity_t *entity, u32 indent);
void free_json(jentity_t **entity);
jcoll_t *get_collection_from_entity(const jentity_t *entity);
jentity_t *create_new_single_entity(const jval_t value, jentity_t *parent);
jentity_t *create_new_pair_entity(dstr_t *key, const jval_t value,
                                  jentity_t *parent);

#endif // !JSON_ENTITIES_H