#ifndef CN_CREATE_C
#define CN_CREATE_C

#ifdef  __cplusplus
extern "C" {
#endif

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

#include "dll-export.h"
#include "cn-cbor/cn-cbor.h"
#include "cbor.h"

#define INIT_CB(v) \
  if (errp) {errp->err = CN_CBOR_NO_ERROR;} \
  (v) = CN_CALLOC_CONTEXT(); \
  if (!(v)) { if (errp) {errp->err = CN_CBOR_ERR_OUT_OF_MEMORY;} return NULL; }

MYLIB_EXPORT
cn_cbor* cn_cbor_map_create(CBOR_CONTEXT_COMMA cn_cbor_errback *errp)
{
  cn_cbor* ret;
  INIT_CB(ret);

  ret->type = CN_CBOR_MAP;
  ret->flags |= CN_CBOR_FL_COUNT;

  return ret;
}

MYLIB_EXPORT
cn_cbor* cn_cbor_data_create(const uint8_t* data, int len
                             CBOR_CONTEXT,
                             cn_cbor_errback *errp)
{
  cn_cbor* ret;
  INIT_CB(ret);

  ret->type = CN_CBOR_BYTES;
  ret->length = len;
  ret->v.str = (const char*) data; // TODO: add v.ustr to the union?

  return ret;
}

MYLIB_EXPORT
cn_cbor* cn_cbor_string_create(const char* data
                               CBOR_CONTEXT,
                               cn_cbor_errback *errp)
{
  cn_cbor* ret;
  INIT_CB(ret);

  ret->type = CN_CBOR_TEXT;
  ret->length = strlen(data);
  ret->v.str = data;

  return ret;
}

MYLIB_EXPORT
cn_cbor* cn_cbor_int_create(int64_t value
                            CBOR_CONTEXT,
                            cn_cbor_errback *errp)
{
  cn_cbor* ret;
  INIT_CB(ret);

  if (value<0) {
    ret->type = CN_CBOR_INT;
    ret->v.sint = value;
  } else {
    ret->type = CN_CBOR_UINT;
    ret->v.uint = value;
  }

  return ret;
}

#ifndef CBOR_NO_FLOAT
cn_cbor* cn_cbor_float_create(float value
                              CBOR_CONTEXT,
                              cn_cbor_errback *errp)
{
  cn_cbor* ret;
  INIT_CB(ret);

  ret->type = CN_CBOR_FLOAT;
  ret->v.f = value;

  return ret;
}

cn_cbor* cn_cbor_double_create(double value
                               CBOR_CONTEXT,
                               cn_cbor_errback *errp)
{
  cn_cbor* ret;
  INIT_CB(ret);

  ret->type = CN_CBOR_DOUBLE;
  ret->v.dbl = value;

  return ret;
}
#endif /* CBOR_NO_FLOAT */

static bool _append_kv(cn_cbor *cb_map, cn_cbor *key, cn_cbor *val)
{
  //Connect key and value and insert them into the map.
  key->parent = cb_map;
  key->next = val;
  val->parent = cb_map;
  val->next = NULL;

  if(cb_map->last_child) {
    cb_map->last_child->next = key;
  } else {
    cb_map->first_child = key;
  }
  cb_map->last_child = val;
  cb_map->length += 2;
  return true;
}

MYLIB_EXPORT
bool cn_cbor_map_put(cn_cbor* cb_map,
                     cn_cbor *cb_key, cn_cbor *cb_value,
                     cn_cbor_errback *errp)
{
  //Make sure input is a map. Otherwise
  if(!cb_map || !cb_key || !cb_value || cb_map->type != CN_CBOR_MAP)
  {
    if (errp) {errp->err = CN_CBOR_ERR_INVALID_PARAMETER;}
    return false;
  }

  return _append_kv(cb_map, cb_key, cb_value);
}

MYLIB_EXPORT
bool cn_cbor_mapput_int(cn_cbor* cb_map,
                        int64_t key, cn_cbor* cb_value
                        CBOR_CONTEXT,
                        cn_cbor_errback *errp)
{
  cn_cbor* cb_key;

  //Make sure input is a map. Otherwise
  if(!cb_map || !cb_value || cb_map->type != CN_CBOR_MAP)
  {
    if (errp) {errp->err = CN_CBOR_ERR_INVALID_PARAMETER;}
    return false;
  }

  cb_key = cn_cbor_int_create(key CBOR_CONTEXT_PARAM, errp);
  if (!cb_key) { return false; }
  return _append_kv(cb_map, cb_key, cb_value);
}

MYLIB_EXPORT
bool cn_cbor_mapput_string(cn_cbor* cb_map,
                           const char* key, cn_cbor* cb_value
                           CBOR_CONTEXT,
                           cn_cbor_errback *errp)
{
  cn_cbor* cb_key;

  //Make sure input is a map. Otherwise
  if(!cb_map || !cb_value || cb_map->type != CN_CBOR_MAP)
  {
    if (errp) {errp->err = CN_CBOR_ERR_INVALID_PARAMETER;}
    return false;
  }

  cb_key = cn_cbor_string_create(key CBOR_CONTEXT_PARAM,  errp);
  if (!cb_key) { return false; }
  return _append_kv(cb_map, cb_key, cb_value);
}

MYLIB_EXPORT
cn_cbor* cn_cbor_array_create(CBOR_CONTEXT_COMMA cn_cbor_errback *errp)
{
  cn_cbor* ret;
  INIT_CB(ret);

  ret->type = CN_CBOR_ARRAY;
  ret->flags |= CN_CBOR_FL_COUNT;

  return ret;
}

MYLIB_EXPORT
bool cn_cbor_array_append(cn_cbor* cb_array,
                          cn_cbor* cb_value,
                          cn_cbor_errback *errp)
{
  //Make sure input is an array.
  if(!cb_array || !cb_value || cb_array->type != CN_CBOR_ARRAY)
  {
    if (errp) {errp->err = CN_CBOR_ERR_INVALID_PARAMETER;}
    return false;
  }

  cb_value->parent = cb_array;
  cb_value->next = NULL;
  if(cb_array->last_child) {
    cb_array->last_child->next = cb_value;
  } else {
    cb_array->first_child = cb_value;
  }
  cb_array->last_child = cb_value;
  cb_array->length++;
  return true;
}

#ifdef  __cplusplus
}
#endif

#endif  /* CN_CBOR_C */
