/*
 * plist.c
 * Builds plist XML structures
 *
 * Copyright (c) 2009-2023 Nikias Bassen, All Rights Reserved.
 * Copyright (c) 2010-2015 Martin Szulecki, All Rights Reserved.
 * Copyright (c) 2008 Zach C., All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#define _GNU_SOURCE 1
#include <string.h>
#include "plist.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <limits.h>
#include <float.h>
#include <ctype.h>

#ifdef WIN32
#include <windows.h>
#else
#include <pthread.h>
#endif

#include <node.h>
#include <node_list.h>
#include <hashtable.h>
#include <ptrarray.h>

extern void plist_xml_init(void);
extern void plist_xml_deinit(void);
extern void plist_bin_init(void);
extern void plist_bin_deinit(void);
extern void plist_json_init(void);
extern void plist_json_deinit(void);
extern void plist_ostep_init(void);
extern void plist_ostep_deinit(void);

static void internal_plist_init(void)
{
    plist_bin_init();
    plist_xml_init();
    plist_json_init();
    plist_ostep_init();
}

static void internal_plist_deinit(void)
{
    plist_bin_deinit();
    plist_xml_deinit();
    plist_json_deinit();
    plist_ostep_deinit();
}

#ifdef WIN32
typedef volatile struct {
    LONG lock;
    int state;
} thread_once_t;

static thread_once_t init_once = {0, 0};
static thread_once_t deinit_once = {0, 0};

static void thread_once(thread_once_t *once_control, void (*init_routine)(void))
{
    while (InterlockedExchange(&(once_control->lock), 1) != 0) {
        Sleep(1);
    }
    if (!once_control->state) {
        once_control->state = 1;
        init_routine();
    }
    InterlockedExchange(&(once_control->lock), 0);
}
#else
static pthread_once_t init_once = PTHREAD_ONCE_INIT;
static pthread_once_t deinit_once = PTHREAD_ONCE_INIT;
#define thread_once pthread_once
#endif

#ifndef HAVE_ATTRIBUTE_CONSTRUCTOR
  #if defined(__llvm__) || defined(__GNUC__)
    #define HAVE_ATTRIBUTE_CONSTRUCTOR
  #endif
#endif

#ifdef HAVE_ATTRIBUTE_CONSTRUCTOR
static void __attribute__((constructor)) libplist_initialize(void)
{
    thread_once(&init_once, internal_plist_init);
}

static void __attribute__((destructor)) libplist_deinitialize(void)
{
    thread_once(&deinit_once, internal_plist_deinit);
}
#elif defined(WIN32)
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved)
{
    switch (dwReason) {
    case DLL_PROCESS_ATTACH:
        thread_once(&init_once, internal_plist_init);
        break;
    case DLL_PROCESS_DETACH:
        thread_once(&deinit_once, internal_plist_deinit);
        break;
    default:
        break;
    }
    return 1;
}
#else
#warning No compiler support for constructor/destructor attributes, some features might not be available.
#endif

#ifndef HAVE_MEMMEM
// see https://sourceware.org/legacy-ml/libc-alpha/2007-12/msg00000.html

#ifndef _LIBC
# define __builtin_expect(expr, val)   (expr)
#endif

#undef memmem

/* Return the first occurrence of NEEDLE in HAYSTACK. */
void* memmem(const void* haystack, size_t haystack_len, const void* needle, size_t needle_len)
{
    /* not really Rabin-Karp, just using additive hashing */
    char* haystack_ = (char*)haystack;
    char* needle_ = (char*)needle;
    int hash = 0;  /* this is the static hash value of the needle */
    int hay_hash = 0;  /* rolling hash over the haystack */
    char* last;
    size_t i;

    if (haystack_len < needle_len)
        return NULL;

    if (!needle_len)
        return haystack_;

    /* initialize hashes */
    for (i = needle_len; i; --i) {
        hash += *needle_++;
        hay_hash += *haystack_++;
    }

    /* iterate over the haystack */
    haystack_ = (char*)haystack;
    needle_ = (char*)needle;
    last = haystack_+(haystack_len - needle_len + 1);
    for (; haystack_ < last; ++haystack_) {
        if (__builtin_expect(hash == hay_hash, 0)
              && *haystack_ == *needle_ /* prevent calling memcmp, was a optimization from existing glibc */
              && !memcmp (haystack_, needle_, needle_len)) {
            return haystack_;
        }
        /* roll the hash */
        hay_hash -= *haystack_;
        hay_hash += *(haystack_+needle_len);
    }
    return NULL;
}
#endif

PLIST_API int plist_is_binary(const char *plist_data, uint32_t length)
{
    if (length < 8) {
        return 0;
    }

    return (memcmp(plist_data, "bplist00", 8) == 0);
}

#define SKIP_WS(blob, pos, len) \
    while (pos < len && ((blob[pos] == ' ') || (blob[pos] == '\t') || (blob[pos] == '\r') || (blob[pos] == '\n'))) pos++;
#define FIND_NEXT(blob, pos, len, chr) \
    while (pos < len && (blob[pos] != chr)) pos++;

PLIST_API plist_err_t plist_from_memory(const char *plist_data, uint32_t length, plist_t *plist, plist_format_t *format)
{
    int res = -1;
    if (!plist) {
        return PLIST_ERR_INVALID_ARG;
    }
    *plist = NULL;
    if (!plist_data || length == 0) {
        return PLIST_ERR_INVALID_ARG;
    }
    plist_format_t fmt = 0;
    if (format) *format = 0;
    if (plist_is_binary(plist_data, length)) {
        res = plist_from_bin(plist_data, length, plist);
        fmt = PLIST_FORMAT_BINARY;
    } else {
        uint32_t pos = 0;
        int is_json = 0;
        int is_xml = 0;
        /* skip whitespace */
        SKIP_WS(plist_data, pos, length);
        if (plist_data[pos] == '<' && (length-pos > 3) && !isxdigit(plist_data[pos+1]) && !isxdigit(plist_data[pos+2]) && !isxdigit(plist_data[pos+3])) {
            is_xml = 1;
        } else if (plist_data[pos] == '[') {
            /* only valid for json */
            is_json = 1;
        } else if (plist_data[pos] == '(') {
            /* only valid for openstep */
        } else if (plist_data[pos] == '{') {
            /* this could be json or openstep */
            pos++;
            SKIP_WS(plist_data, pos, length);
            if (plist_data[pos] == '"') {
                /* still could be both */
                pos++;
                do {
                    FIND_NEXT(plist_data, pos, length, '"');
                    if (plist_data[pos-1] != '\\') {
                        break;
                    }
                    pos++;
                } while (pos < length);
                if (plist_data[pos] == '"') {
                    pos++;
                    SKIP_WS(plist_data, pos, length);
                    if (plist_data[pos] == ':') {
                        /* this is definitely json */
                        is_json = 1;
                    }
                }
            }
        }
        if (is_xml) {
            res = plist_from_xml(plist_data, length, plist);
            fmt = PLIST_FORMAT_XML;
        } else if (is_json) {
            res = plist_from_json(plist_data, length, plist);
            fmt = PLIST_FORMAT_JSON;
        } else {
            res = plist_from_openstep(plist_data, length, plist);
            fmt = PLIST_FORMAT_OSTEP;
        }
    }
    if (format && res == PLIST_ERR_SUCCESS) {
        *format = fmt;
    }
    return res;
}

PLIST_API plist_err_t plist_read_from_file(const char *filename, plist_t *plist, plist_format_t *format)
{
    if (!filename || !plist) {
        return PLIST_ERR_INVALID_ARG;
    }
    FILE *f = fopen(filename, "rb");
    if (!f) {
        return PLIST_ERR_IO;
    }
    struct stat fst;
    fstat(fileno(f), &fst);
    if (fst.st_size > UINT32_MAX) {
        return PLIST_ERR_NO_MEM;
    }
    uint32_t total = (uint32_t)fst.st_size;
    if (total == 0) {
        return PLIST_ERR_PARSE;
    }
    char *buf = malloc(total);
    if (!buf) {
        fclose(f);
        return PLIST_ERR_NO_MEM;
    }
    uint32_t done = 0;
    while (done < total) {
        ssize_t r = fread(buf + done, 1, total - done, f);
        if (r <= 0) {
            break;
        }
        done += r;
    }
    fclose(f);
    if (done < total) {
        free(buf);
        return PLIST_ERR_IO;
    }
    plist_err_t res = plist_from_memory(buf, total, plist, format);
    free(buf);
    return res;
}

plist_t plist_new_node(plist_data_t data)
{
    return (plist_t) node_create(NULL, data);
}

plist_data_t plist_get_data(plist_t node)
{
    if (!node)
        return NULL;
    return ((node_t)node)->data;
}

plist_data_t plist_new_plist_data(void)
{
    plist_data_t data = (plist_data_t) calloc(sizeof(struct plist_data_s), 1);
    return data;
}

static unsigned int dict_key_hash(const void *data)
{
    plist_data_t keydata = (plist_data_t)data;
    unsigned int hash = 5381;
    size_t i;
    char *str = keydata->strval;
    for (i = 0; i < keydata->length; str++, i++) {
        hash = ((hash << 5) + hash) + *str;
    }
    return hash;
}

static int dict_key_compare(const void* a, const void* b)
{
    plist_data_t data_a = (plist_data_t)a;
    plist_data_t data_b = (plist_data_t)b;
    if (data_a->strval == NULL || data_b->strval == NULL) {
        return FALSE;
    }
    if (data_a->length != data_b->length) {
        return FALSE;
    }
    return (strcmp(data_a->strval, data_b->strval) == 0) ? TRUE : FALSE;
}

void plist_free_data(plist_data_t data)
{
    if (data)
    {
        switch (data->type)
        {
        case PLIST_KEY:
        case PLIST_STRING:
            free(data->strval);
            break;
        case PLIST_DATA:
            free(data->buff);
            break;
        case PLIST_ARRAY:
            ptr_array_free(data->hashtable);
            break;
        case PLIST_DICT:
            hash_table_destroy(data->hashtable);
            break;
        default:
            break;
        }
        free(data);
    }
}

static int plist_free_node(node_t node)
{
    plist_data_t data = NULL;
    int node_index = node_detach(node->parent, node);
    data = plist_get_data(node);
    plist_free_data(data);
    node->data = NULL;

    node_t ch;
    for (ch = node_first_child(node); ch; ) {
        node_t next = node_next_sibling(ch);
        plist_free_node(ch);
        ch = next;
    }

    node_destroy(node);

    return node_index;
}

PLIST_API plist_t plist_new_dict(void)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_DICT;
    return plist_new_node(data);
}

PLIST_API plist_t plist_new_array(void)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_ARRAY;
    return plist_new_node(data);
}

//These nodes should not be handled by users
static plist_t plist_new_key(const char *val)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_KEY;
    data->strval = strdup(val);
    data->length = strlen(val);
    return plist_new_node(data);
}

PLIST_API plist_t plist_new_string(const char *val)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_STRING;
    data->strval = strdup(val);
    data->length = strlen(val);
    return plist_new_node(data);
}

PLIST_API plist_t plist_new_bool(uint8_t val)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_BOOLEAN;
    data->boolval = val;
    data->length = sizeof(uint8_t);
    return plist_new_node(data);
}

PLIST_API plist_t plist_new_uint(uint64_t val)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_INT;
    data->intval = val;
    data->length = (val > INT_MAX) ? sizeof(uint64_t)*2 : sizeof(uint64_t);
    return plist_new_node(data);
}

PLIST_API plist_t plist_new_int(int64_t val)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_INT;
    data->intval = val;
    data->length = sizeof(uint64_t);
    return plist_new_node(data);
}

PLIST_API plist_t plist_new_uid(uint64_t val)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_UID;
    data->intval = val;
    data->length = sizeof(uint64_t);
    return plist_new_node(data);
}

PLIST_API plist_t plist_new_real(double val)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_REAL;
    data->realval = val;
    data->length = sizeof(double);
    return plist_new_node(data);
}

PLIST_API plist_t plist_new_data(const char *val, uint64_t length)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_DATA;
    data->buff = (uint8_t *) malloc(length);
    memcpy(data->buff, val, length);
    data->length = length;
    return plist_new_node(data);
}

PLIST_API plist_t plist_new_date(int32_t sec, int32_t usec)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_DATE;
    data->realval = (double)sec + (double)usec / 1000000;
    data->length = sizeof(double);
    return plist_new_node(data);
}

PLIST_API plist_t plist_new_null(void)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_NULL;
    data->intval = 0;
    data->length = 0;
    return plist_new_node(data);
}

PLIST_API void plist_free(plist_t plist)
{
    if (plist)
    {
        plist_free_node(plist);
    }
}

PLIST_API void plist_mem_free(void* ptr)
{
    if (ptr)
    {
        free(ptr);
    }
}

static plist_t plist_copy_node(node_t node)
{
    plist_type node_type = PLIST_NONE;
    plist_t newnode = NULL;
    plist_data_t data = plist_get_data(node);
    plist_data_t newdata = plist_new_plist_data();

    assert(data);				// plist should always have data
    assert(newdata);

    memcpy(newdata, data, sizeof(struct plist_data_s));

    node_type = plist_get_node_type(node);
    switch (node_type) {
        case PLIST_DATA:
            newdata->buff = (uint8_t *) malloc(data->length);
            memcpy(newdata->buff, data->buff, data->length);
            break;
        case PLIST_KEY:
        case PLIST_STRING:
            newdata->strval = strdup(data->strval);
            break;
        case PLIST_ARRAY:
            if (data->hashtable) {
                ptrarray_t* pa = ptr_array_new(((ptrarray_t*)data->hashtable)->capacity);
                assert(pa);
                newdata->hashtable = pa;
            }
            break;
        case PLIST_DICT:
            if (data->hashtable) {
                hashtable_t* ht = hash_table_new(dict_key_hash, dict_key_compare, NULL);
                assert(ht);
                newdata->hashtable = ht;
            }
            break;
        default:
            break;
    }
    newnode = plist_new_node(newdata);

    node_t ch;
    unsigned int node_index = 0;
    for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) {
        /* copy child node */
        plist_t newch = plist_copy_node(ch);
        /* attach to new parent node */
        node_attach(newnode, newch);
        /* if needed, add child node to lookup table of parent node */
        switch (node_type) {
            case PLIST_ARRAY:
                if (newdata->hashtable) {
                    ptr_array_add((ptrarray_t*)newdata->hashtable, newch);
                }
                break;
            case PLIST_DICT:
                if (newdata->hashtable && (node_index % 2 != 0)) {
                    hash_table_insert((hashtable_t*)newdata->hashtable, (node_prev_sibling((node_t)newch))->data, newch);
                }
                break;
            default:
                break;
        }
        node_index++;
    }
    return newnode;
}

PLIST_API plist_t plist_copy(plist_t node)
{
    return node ? plist_copy_node(node) : NULL;
}

PLIST_API uint32_t plist_array_get_size(plist_t node)
{
    uint32_t ret = 0;
    if (node && PLIST_ARRAY == plist_get_node_type(node))
    {
        ret = node_n_children(node);
    }
    return ret;
}

PLIST_API plist_t plist_array_get_item(plist_t node, uint32_t n)
{
    plist_t ret = NULL;
    if (node && PLIST_ARRAY == plist_get_node_type(node) && n < INT_MAX)
    {
        ptrarray_t *pa = ((plist_data_t)((node_t)node)->data)->hashtable;
        if (pa) {
            ret = (plist_t)ptr_array_index(pa, n);
        } else {
            ret = (plist_t)node_nth_child(node, n);
        }
    }
    return ret;
}

PLIST_API uint32_t plist_array_get_item_index(plist_t node)
{
    plist_t father = plist_get_parent(node);
    if (PLIST_ARRAY == plist_get_node_type(father))
    {
        return node_child_position(father, node);
    }
    return UINT_MAX;
}

static void _plist_array_post_insert(plist_t node, plist_t item, long n)
{
    ptrarray_t *pa = ((plist_data_t)((node_t)node)->data)->hashtable;
    if (pa) {
        /* store pointer to item in array */
        ptr_array_insert(pa, item, n);
    } else {
        if (((node_t)node)->count > 100) {
            /* make new lookup array */
            pa = ptr_array_new(128);
            plist_t current = NULL;
            for (current = (plist_t)node_first_child(node);
                 pa && current;
                 current = (plist_t)node_next_sibling(current))
            {
                ptr_array_add(pa, current);
            }
            ((plist_data_t)((node_t)node)->data)->hashtable = pa;
        }
    }
}

PLIST_API void plist_array_set_item(plist_t node, plist_t item, uint32_t n)
{
    if (node && PLIST_ARRAY == plist_get_node_type(node) && n < INT_MAX)
    {
        plist_t old_item = plist_array_get_item(node, n);
        if (old_item)
        {
            int idx = plist_free_node(old_item);
            assert(idx >= 0);
            if (idx < 0) {
                return;
            }
            node_insert(node, idx, item);
            ptrarray_t* pa = ((plist_data_t)((node_t)node)->data)->hashtable;
            if (pa) {
                ptr_array_set(pa, item, idx);
            }
        }
    }
}

PLIST_API void plist_array_append_item(plist_t node, plist_t item)
{
    if (node && PLIST_ARRAY == plist_get_node_type(node))
    {
        node_attach(node, item);
        _plist_array_post_insert(node, item, -1);
    }
}

PLIST_API void plist_array_insert_item(plist_t node, plist_t item, uint32_t n)
{
    if (node && PLIST_ARRAY == plist_get_node_type(node) && n < INT_MAX)
    {
        node_insert(node, n, item);
        _plist_array_post_insert(node, item, (long)n);
    }
}

PLIST_API void plist_array_remove_item(plist_t node, uint32_t n)
{
    if (node && PLIST_ARRAY == plist_get_node_type(node) && n < INT_MAX)
    {
        plist_t old_item = plist_array_get_item(node, n);
        if (old_item)
        {
            ptrarray_t* pa = ((plist_data_t)((node_t)node)->data)->hashtable;
            if (pa) {
                ptr_array_remove(pa, n);
            }
            plist_free(old_item);
        }
    }
}

PLIST_API void plist_array_item_remove(plist_t node)
{
    plist_t father = plist_get_parent(node);
    if (PLIST_ARRAY == plist_get_node_type(father))
    {
        int n = node_child_position(father, node);
        if (n < 0) return;
        ptrarray_t* pa = ((plist_data_t)((node_t)father)->data)->hashtable;
        if (pa) {
            ptr_array_remove(pa, n);
        }
        plist_free(node);
    }
}

PLIST_API void plist_array_new_iter(plist_t node, plist_array_iter *iter)
{
    if (iter)
    {
        *iter = malloc(sizeof(node_t));
        *((node_t*)(*iter)) = node_first_child(node);
    }
}

PLIST_API void plist_array_next_item(plist_t node, plist_array_iter iter, plist_t *item)
{
    node_t* iter_node = (node_t*)iter;

    if (item)
    {
        *item = NULL;
    }

    if (node && PLIST_ARRAY == plist_get_node_type(node) && *iter_node)
    {
        if (item)
        {
            *item = (plist_t)(*iter_node);
        }
        *iter_node = node_next_sibling(*iter_node);
    }
}

PLIST_API uint32_t plist_dict_get_size(plist_t node)
{
    uint32_t ret = 0;
    if (node && PLIST_DICT == plist_get_node_type(node))
    {
        ret = node_n_children(node) / 2;
    }
    return ret;
}

PLIST_API void plist_dict_new_iter(plist_t node, plist_dict_iter *iter)
{
    if (iter)
    {
        *iter = malloc(sizeof(node_t));
        *((node_t*)(*iter)) = node_first_child(node);
    }
}

PLIST_API void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val)
{
    node_t* iter_node = (node_t*)iter;

    if (key)
    {
        *key = NULL;
    }
    if (val)
    {
        *val = NULL;
    }

    if (node && PLIST_DICT == plist_get_node_type(node) && *iter_node)
    {
        if (key)
        {
            plist_get_key_val((plist_t)(*iter_node), key);
        }
        *iter_node = node_next_sibling(*iter_node);
        if (val)
        {
            *val = (plist_t)(*iter_node);
        }
        *iter_node = node_next_sibling(*iter_node);
    }
}

PLIST_API void plist_dict_get_item_key(plist_t node, char **key)
{
    plist_t father = plist_get_parent(node);
    if (PLIST_DICT == plist_get_node_type(father))
    {
        plist_get_key_val( (plist_t) node_prev_sibling(node), key);
    }
}

PLIST_API plist_t plist_dict_item_get_key(plist_t node)
{
    plist_t ret = NULL;
    plist_t father = plist_get_parent(node);
    if (PLIST_DICT == plist_get_node_type(father))
    {
        ret = (plist_t)node_prev_sibling(node);
    }
    return ret;
}

PLIST_API plist_t plist_dict_get_item(plist_t node, const char* key)
{
    plist_t ret = NULL;

    if (node && PLIST_DICT == plist_get_node_type(node))
    {
        plist_data_t data = plist_get_data(node);
        hashtable_t *ht = (hashtable_t*)data->hashtable;
        if (ht) {
            struct plist_data_s sdata;
            sdata.strval = (char*)key;
            sdata.length = strlen(key);
            ret = (plist_t)hash_table_lookup(ht, &sdata);
        } else {
            plist_t current = NULL;
            for (current = (plist_t)node_first_child(node);
                current;
                current = (plist_t)node_next_sibling(node_next_sibling(current)))
            {
                data = plist_get_data(current);
                assert( PLIST_KEY == plist_get_node_type(current) );

                if (data && !strcmp(key, data->strval))
                {
                    ret = (plist_t)node_next_sibling(current);
                    break;
                }
            }
        }
    }
    return ret;
}

PLIST_API void plist_dict_set_item(plist_t node, const char* key, plist_t item)
{
    if (node && PLIST_DICT == plist_get_node_type(node)) {
        node_t old_item = plist_dict_get_item(node, key);
        plist_t key_node = NULL;
        if (old_item) {
            int idx = plist_free_node(old_item);
            assert(idx >= 0);
            if (idx < 0) {
                return;
            }
            node_insert(node, idx, item);
            key_node = node_prev_sibling(item);
        } else {
            key_node = plist_new_key(key);
            node_attach(node, key_node);
            node_attach(node, item);
        }

        hashtable_t *ht = ((plist_data_t)((node_t)node)->data)->hashtable;
        if (ht) {
            /* store pointer to item in hash table */
            hash_table_insert(ht, (plist_data_t)((node_t)key_node)->data, item);
        } else {
            if (((node_t)node)->count > 500) {
                /* make new hash table */
                ht = hash_table_new(dict_key_hash, dict_key_compare, NULL);
                /* calculate the hashes for all entries we have so far */
                plist_t current = NULL;
                for (current = (plist_t)node_first_child(node);
                     ht && current;
                     current = (plist_t)node_next_sibling(node_next_sibling(current)))
                {
                    hash_table_insert(ht, ((node_t)current)->data, node_next_sibling(current));
                }
                ((plist_data_t)((node_t)node)->data)->hashtable = ht;
            }
        }
    }
}

PLIST_API void plist_dict_remove_item(plist_t node, const char* key)
{
    if (node && PLIST_DICT == plist_get_node_type(node))
    {
        plist_t old_item = plist_dict_get_item(node, key);
        if (old_item)
        {
            plist_t key_node = node_prev_sibling(old_item);
            hashtable_t* ht = ((plist_data_t)((node_t)node)->data)->hashtable;
            if (ht) {
                hash_table_remove(ht, ((node_t)key_node)->data);
            }
            plist_free(key_node);
            plist_free(old_item);
        }
    }
}

PLIST_API void plist_dict_merge(plist_t *target, plist_t source)
{
	if (!target || !*target || (plist_get_node_type(*target) != PLIST_DICT) || !source || (plist_get_node_type(source) != PLIST_DICT))
		return;

	char* key = NULL;
	plist_dict_iter it = NULL;
	plist_t subnode = NULL;
	plist_dict_new_iter(source, &it);
	if (!it)
		return;

	do {
		plist_dict_next_item(source, it, &key, &subnode);
		if (!key)
			break;

		plist_dict_set_item(*target, key, plist_copy(subnode));
		free(key);
		key = NULL;
	} while (1);
	free(it);
}

PLIST_API plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v)
{
    plist_t current = plist;
    plist_type type = PLIST_NONE;
    uint32_t i = 0;

    for (i = 0; i < length && current; i++)
    {
        type = plist_get_node_type(current);

        if (type == PLIST_ARRAY)
        {
            uint32_t n = va_arg(v, uint32_t);
            current = plist_array_get_item(current, n);
        }
        else if (type == PLIST_DICT)
        {
            const char* key = va_arg(v, const char*);
            current = plist_dict_get_item(current, key);
        }
    }
    return current;
}

PLIST_API plist_t plist_access_path(plist_t plist, uint32_t length, ...)
{
    plist_t ret = NULL;
    va_list v;

    va_start(v, length);
    ret = plist_access_pathv(plist, length, v);
    va_end(v);
    return ret;
}

static void plist_get_type_and_value(plist_t node, plist_type * type, void *value, uint64_t * length)
{
    plist_data_t data = NULL;

    if (!node)
        return;

    data = plist_get_data(node);

    *type = data->type;
    *length = data->length;

    switch (*type)
    {
    case PLIST_BOOLEAN:
        *((char *) value) = data->boolval;
        break;
    case PLIST_INT:
    case PLIST_UID:
        *((uint64_t *) value) = data->intval;
        break;
    case PLIST_REAL:
    case PLIST_DATE:
        *((double *) value) = data->realval;
        break;
    case PLIST_KEY:
    case PLIST_STRING:
        *((char **) value) = strdup(data->strval);
        break;
    case PLIST_DATA:
        *((uint8_t **) value) = (uint8_t *) malloc(*length * sizeof(uint8_t));
        memcpy(*((uint8_t **) value), data->buff, *length * sizeof(uint8_t));
        break;
    case PLIST_ARRAY:
    case PLIST_DICT:
    default:
        break;
    }
}

PLIST_API plist_t plist_get_parent(plist_t node)
{
    return node ? (plist_t) ((node_t) node)->parent : NULL;
}

PLIST_API plist_type plist_get_node_type(plist_t node)
{
    if (node)
    {
        plist_data_t data = plist_get_data(node);
        if (data)
            return data->type;
    }
    return PLIST_NONE;
}

PLIST_API void plist_get_key_val(plist_t node, char **val)
{
    if (!node || !val)
        return;
    plist_type type = plist_get_node_type(node);
    uint64_t length = 0;
    if (PLIST_KEY != type)
        return;
    plist_get_type_and_value(node, &type, (void *) val, &length);
    if (!*val)
        return;
    assert(length == strlen(*val));
}

PLIST_API void plist_get_string_val(plist_t node, char **val)
{
    if (!node || !val)
        return;
    plist_type type = plist_get_node_type(node);
    uint64_t length = 0;
    if (PLIST_STRING != type)
        return;
    plist_get_type_and_value(node, &type, (void *) val, &length);
    if (!*val)
        return;
    assert(length == strlen(*val));
}

PLIST_API const char* plist_get_string_ptr(plist_t node, uint64_t* length)
{
    if (!node)
        return NULL;
    plist_type type = plist_get_node_type(node);
    if (PLIST_STRING != type)
        return NULL;
    plist_data_t data = plist_get_data(node);
    if (length)
        *length = data->length;
    return (const char*)data->strval;
}

PLIST_API void plist_get_bool_val(plist_t node, uint8_t * val)
{
    if (!node || !val)
        return;
    plist_type type = plist_get_node_type(node);
    uint64_t length = 0;
    if (PLIST_BOOLEAN != type)
        return;
    plist_get_type_and_value(node, &type, (void *) val, &length);
    assert(length == sizeof(uint8_t));
}

PLIST_API void plist_get_uint_val(plist_t node, uint64_t * val)
{
    if (!node || !val)
        return;
    plist_type type = plist_get_node_type(node);
    uint64_t length = 0;
    if (PLIST_INT != type)
        return;
    plist_get_type_and_value(node, &type, (void *) val, &length);
    assert(length == sizeof(uint64_t) || length == 16);
}

PLIST_API void plist_get_int_val(plist_t node, int64_t * val)
{
    plist_get_uint_val(node, (uint64_t*)val);
}

PLIST_API void plist_get_uid_val(plist_t node, uint64_t * val)
{
    if (!node || !val)
        return;
    plist_type type = plist_get_node_type(node);
    uint64_t length = 0;
    if (PLIST_UID != type)
        return;
    plist_get_type_and_value(node, &type, (void *) val, &length);
    assert(length == sizeof(uint64_t));
}

PLIST_API void plist_get_real_val(plist_t node, double *val)
{
    if (!node || !val)
        return;
    plist_type type = plist_get_node_type(node);
    uint64_t length = 0;
    if (PLIST_REAL != type)
        return;
    plist_get_type_and_value(node, &type, (void *) val, &length);
    assert(length == sizeof(double));
}

PLIST_API void plist_get_data_val(plist_t node, char **val, uint64_t * length)
{
    if (!node || !val || !length)
        return;
    plist_type type = plist_get_node_type(node);
    if (PLIST_DATA != type)
        return;
    plist_get_type_and_value(node, &type, (void *) val, length);
}

PLIST_API const char* plist_get_data_ptr(plist_t node, uint64_t* length)
{
    if (!node || !length)
        return NULL;
    plist_type type = plist_get_node_type(node);
    if (PLIST_DATA != type)
        return NULL;
    plist_data_t data = plist_get_data(node);
    *length = data->length;
    return (const char*)data->buff;
}

PLIST_API void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec)
{
    if (!node)
        return;
    plist_type type = plist_get_node_type(node);
    uint64_t length = 0;
    double val = 0;
    if (PLIST_DATE != type)
        return;
    plist_get_type_and_value(node, &type, (void *) &val, &length);
    assert(length == sizeof(double));
    if (sec)
        *sec = (int32_t)val;
    if (usec)
    {
	val = fabs((val - (int64_t)val) * 1000000);
        *usec = (int32_t)val;
    }
}

int plist_data_compare(const void *a, const void *b)
{
    plist_data_t val_a = NULL;
    plist_data_t val_b = NULL;

    if (!a || !b)
        return FALSE;

    if (!((node_t) a)->data || !((node_t) b)->data)
        return FALSE;

    val_a = plist_get_data((plist_t) a);
    val_b = plist_get_data((plist_t) b);

    if (val_a->type != val_b->type)
        return FALSE;

    switch (val_a->type)
    {
    case PLIST_BOOLEAN:
    case PLIST_NULL:
    case PLIST_INT:
    case PLIST_REAL:
    case PLIST_DATE:
    case PLIST_UID:
        if (val_a->length != val_b->length)
            return FALSE;
        return val_a->intval == val_b->intval;	//it is an union so this is sufficient

    case PLIST_KEY:
    case PLIST_STRING:
        return strcmp(val_a->strval, val_b->strval) == 0;

    case PLIST_DATA:
        if (val_a->length != val_b->length)
            return FALSE;
        return memcmp(val_a->buff, val_b->buff, val_a->length) == 0;

    case PLIST_ARRAY:
    case PLIST_DICT:
        //compare pointer
        return a == b;

    default:
        break;
    }
    return FALSE;
}

PLIST_API char plist_compare_node_value(plist_t node_l, plist_t node_r)
{
    return plist_data_compare(node_l, node_r);
}

static void plist_set_element_val(plist_t node, plist_type type, const void *value, uint64_t length)
{
    //free previous allocated buffer
    plist_data_t data = plist_get_data(node);
    assert(data);				// a node should always have data attached

    switch (data->type)
    {
    case PLIST_KEY:
    case PLIST_STRING:
        free(data->strval);
        data->strval = NULL;
        break;
    case PLIST_DATA:
        free(data->buff);
        data->buff = NULL;
        break;
    default:
        break;
    }

    //now handle value

    data->type = type;
    data->length = length;

    switch (type)
    {
    case PLIST_BOOLEAN:
        data->boolval = *((char *) value);
        break;
    case PLIST_INT:
    case PLIST_UID:
        data->intval = *((uint64_t *) value);
        break;
    case PLIST_REAL:
    case PLIST_DATE:
        data->realval = *((double *) value);
        break;
    case PLIST_KEY:
    case PLIST_STRING:
        data->strval = strdup((char *) value);
        break;
    case PLIST_DATA:
        data->buff = (uint8_t *) malloc(length);
        memcpy(data->buff, value, length);
        break;
    case PLIST_ARRAY:
    case PLIST_DICT:
    default:
        break;
    }
}

PLIST_API void plist_set_key_val(plist_t node, const char *val)
{
    plist_t father = plist_get_parent(node);
    plist_t item = plist_dict_get_item(father, val);
    if (item) {
        return;
    }
    plist_set_element_val(node, PLIST_KEY, val, strlen(val));
}

PLIST_API void plist_set_string_val(plist_t node, const char *val)
{
    plist_set_element_val(node, PLIST_STRING, val, strlen(val));
}

PLIST_API void plist_set_bool_val(plist_t node, uint8_t val)
{
    plist_set_element_val(node, PLIST_BOOLEAN, &val, sizeof(uint8_t));
}

PLIST_API void plist_set_uint_val(plist_t node, uint64_t val)
{
    plist_set_element_val(node, PLIST_INT, &val, (val > INT64_MAX) ? sizeof(uint64_t)*2 : sizeof(uint64_t));
}

PLIST_API void plist_set_int_val(plist_t node, int64_t val)
{
    plist_set_element_val(node, PLIST_INT, &val, sizeof(uint64_t));
}

PLIST_API void plist_set_uid_val(plist_t node, uint64_t val)
{
    plist_set_element_val(node, PLIST_UID, &val, sizeof(uint64_t));
}

PLIST_API void plist_set_real_val(plist_t node, double val)
{
    plist_set_element_val(node, PLIST_REAL, &val, sizeof(double));
}

PLIST_API void plist_set_data_val(plist_t node, const char *val, uint64_t length)
{
    plist_set_element_val(node, PLIST_DATA, val, length);
}

PLIST_API void plist_set_date_val(plist_t node, int32_t sec, int32_t usec)
{
    double val = (double)sec + (double)usec / 1000000;
    plist_set_element_val(node, PLIST_DATE, &val, sizeof(struct timeval));
}

PLIST_API int plist_bool_val_is_true(plist_t boolnode)
{
    if (!PLIST_IS_BOOLEAN(boolnode)) {
        return 0;
    }
    uint8_t bv = 0;
    plist_get_bool_val(boolnode, &bv);
    return (bv == 1);
}

PLIST_API int plist_int_val_is_negative(plist_t intnode)
{
    if (!PLIST_IS_INT(intnode)) {
        return 0;
    }
    plist_data_t data = plist_get_data(intnode);
    if (data->length == 16) {
        return 0;
    }
    if ((int64_t)data->intval < 0) {
        return 1;
    }
    return 0;
}

PLIST_API int plist_int_val_compare(plist_t uintnode, int64_t cmpval)
{
    if (!PLIST_IS_INT(uintnode)) {
        return -1;
    }
    int64_t uintval = 0;
    plist_get_int_val(uintnode, &uintval);
    if (uintval == cmpval) {
        return 0;
    }

    if (uintval < cmpval) {
        return -1;
    }

    return 1;
}

PLIST_API int plist_uint_val_compare(plist_t uintnode, uint64_t cmpval)
{
    if (!PLIST_IS_INT(uintnode)) {
        return -1;
    }
    uint64_t uintval = 0;
    plist_get_uint_val(uintnode, &uintval);
    if (uintval == cmpval) {
        return 0;
    }

    if (uintval < cmpval) {
        return -1;
    }

    return 1;
}

PLIST_API int plist_uid_val_compare(plist_t uidnode, uint64_t cmpval)
{
    if (!PLIST_IS_UID(uidnode)) {
        return -1;
    }
    uint64_t uidval = 0;
    plist_get_uid_val(uidnode, &uidval);
    if (uidval == cmpval) {
        return 0;
    }

    if (uidval < cmpval) {
        return -1;
    }

    return 1;
}

PLIST_API int plist_real_val_compare(plist_t realnode, double cmpval)
{
    if (!PLIST_IS_REAL(realnode)) {
        return -1;
    }
    double a = 0;
    double b = cmpval;
    plist_get_real_val(realnode, &a);
    double abs_a = fabs(a);
    double abs_b = fabs(b);
    double diff = fabs(a - b);
    if (a == b) {
        return 0;
    }

    if (a == 0 || b == 0 || (abs_a + abs_b < DBL_MIN)) {
        if (diff < (DBL_EPSILON * DBL_MIN)) {
            return 0;
        }

        if (a < b) {
            return -1;
        }
    } else {
        if ((diff / fmin(abs_a + abs_b, DBL_MAX)) < DBL_EPSILON) {
            return 0;
        }

        if (a < b) {
            return -1;
        }
    }
    return 1;
}

PLIST_API int plist_date_val_compare(plist_t datenode, int32_t cmpsec, int32_t cmpusec)
{
    if (!PLIST_IS_DATE(datenode)) {
        return -1;
    }
    int32_t sec = 0;
    int32_t usec = 0;
    plist_get_date_val(datenode, &sec, &usec);
    uint64_t dateval = ((int64_t)sec << 32) | usec;
    uint64_t cmpval = ((int64_t)cmpsec << 32) | cmpusec;
    if (dateval == cmpval) {
        return 0;
    }

    if (dateval < cmpval) {
        return -1;
    }

    return 1;
}

PLIST_API int plist_string_val_compare(plist_t strnode, const char* cmpval)
{
    if (!PLIST_IS_STRING(strnode)) {
        return -1;
    }
    plist_data_t data = plist_get_data(strnode);
    return strcmp(data->strval, cmpval);
}

PLIST_API int plist_string_val_compare_with_size(plist_t strnode, const char* cmpval, size_t n)
{
    if (!PLIST_IS_STRING(strnode)) {
        return -1;
    }
    plist_data_t data = plist_get_data(strnode);
    return strncmp(data->strval, cmpval, n);
}

PLIST_API int plist_string_val_contains(plist_t strnode, const char* substr)
{
    if (!PLIST_IS_STRING(strnode)) {
        return 0;
    }
    plist_data_t data = plist_get_data(strnode);
    return (strstr(data->strval, substr) != NULL);
}

PLIST_API int plist_key_val_compare(plist_t keynode, const char* cmpval)
{
    if (!PLIST_IS_KEY(keynode)) {
        return -1;
    }
    plist_data_t data = plist_get_data(keynode);
    return strcmp(data->strval, cmpval);
}

PLIST_API int plist_key_val_compare_with_size(plist_t keynode, const char* cmpval, size_t n)
{
    if (!PLIST_IS_KEY(keynode)) {
        return -1;
    }
    plist_data_t data = plist_get_data(keynode);
    return strncmp(data->strval, cmpval, n);
}

PLIST_API int plist_key_val_contains(plist_t keynode, const char* substr)
{
    if (!PLIST_IS_KEY(keynode)) {
        return 0;
    }
    plist_data_t data = plist_get_data(keynode);
    return (strstr(data->strval, substr) != NULL);
}

PLIST_API int plist_data_val_compare(plist_t datanode, const uint8_t* cmpval, size_t n)
{
    if (!PLIST_IS_DATA(datanode)) {
        return -1;
    }
    plist_data_t data = plist_get_data(datanode);
    if (data->length < n) {
        return -1;
    }

    if (data->length > n) {
        return 1;
    }

    return memcmp(data->buff, cmpval, n);
}

PLIST_API int plist_data_val_compare_with_size(plist_t datanode, const uint8_t* cmpval, size_t n)
{
    if (!PLIST_IS_DATA(datanode)) {
        return -1;
    }
    plist_data_t data = plist_get_data(datanode);
    if (data->length < n) {
        return -1;
    }
    return memcmp(data->buff, cmpval, n);
}

PLIST_API int plist_data_val_contains(plist_t datanode, const uint8_t* cmpval, size_t n)
{
    if (!PLIST_IS_DATA(datanode)) {
        return -1;
    }
    plist_data_t data = plist_get_data(datanode);
    return (memmem(data->buff, data->length, cmpval, n) != NULL);
}

extern void plist_xml_set_debug(int debug);
extern void plist_bin_set_debug(int debug);
extern void plist_json_set_debug(int debug);
extern void plist_ostep_set_debug(int debug);

PLIST_API void plist_set_debug(int debug)
{
    plist_xml_set_debug(debug);
    plist_bin_set_debug(debug);
    plist_json_set_debug(debug);
    plist_ostep_set_debug(debug);
}

PLIST_API void plist_sort(plist_t plist)
{
    if (!plist) {
        return;
    }
    if (PLIST_IS_ARRAY(plist)) {
        uint32_t n = plist_array_get_size(plist);
        uint32_t i = 0;
        for (i = 0; i < n; i++) {
            plist_sort(plist_array_get_item(plist, i));
        }
    } else if (PLIST_IS_DICT(plist)) {
        node_t node = (node_t)plist;
        node_t ch;
        for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) {
            ch = node_next_sibling(ch);
            plist_sort((plist_t)ch);
        }
        #define KEY_DATA(x) (x->data)
        #define NEXT_KEY(x) (x->next->next)
        #define KEY_STRVAL(x) ((plist_data_t)(KEY_DATA(x)))->strval
        int swapped = 0;
        do {
            swapped = 0;
            node_t lptr = NULL;
            node_t cur_key = node_first_child((node_t)plist);

            while (NEXT_KEY(cur_key) != lptr) {
                node_t next_key = NEXT_KEY(cur_key);
                if (strcmp(KEY_STRVAL(cur_key), KEY_STRVAL(next_key)) > 0) {
                    node_t cur_val = cur_key->next;
                    node_t next_val = next_key->next;
                    // we need to swap 2 consecutive nodes with the 2 after them
                    // a -> b -> [c] -> [d] -> [e] -> [f] -> g -> h
                    //              cur           next
                    // swapped:
                    // a -> b -> [e] -> [f] -> [c] -> [d] -> g -> h
                    //              next           cur
                    node_t tmp_prev = cur_key->prev;
                    node_t tmp_next = next_val->next;
                    cur_key->prev = next_val;
                    cur_val->next = tmp_next;
                    next_val->next = cur_key;
                    next_key->prev = tmp_prev;
                    if (tmp_prev) {
                        tmp_prev->next = next_key;
                    } else {
                        ((node_t)plist)->children->begin = next_key;
                    }
                    if (tmp_next) {
                        tmp_next->prev = cur_val;
                    } else {
                        ((node_t)plist)->children->end = cur_val;
                    }
                    cur_key = next_key;
                    swapped = 1;
                }
                cur_key = NEXT_KEY(cur_key);
            }
            lptr = cur_key;
        } while (swapped);
    }
}

PLIST_API plist_err_t plist_write_to_string(plist_t plist, char **output, uint32_t* length, plist_format_t format, plist_write_options_t options)
{
    plist_err_t err = PLIST_ERR_UNKNOWN;
    switch (format) {
        case PLIST_FORMAT_XML:
            err = plist_to_xml(plist, output, length);
            break;
        case PLIST_FORMAT_JSON:
            err = plist_to_json(plist, output, length, ((options & PLIST_OPT_COMPACT) == 0));
            break;
        case PLIST_FORMAT_OSTEP:
            err = plist_to_openstep(plist, output, length, ((options & PLIST_OPT_COMPACT) == 0));
            break;
        case PLIST_FORMAT_PRINT:
            err = plist_write_to_string_default(plist, output, length, options);
            break;
        case PLIST_FORMAT_LIMD:
            err = plist_write_to_string_limd(plist, output, length, options);
            break;
        case PLIST_FORMAT_PLUTIL:
            err = plist_write_to_string_plutil(plist, output, length, options);
            break;
        default:
            // unsupported output format
            err = PLIST_ERR_FORMAT;
            break;
    }
    return err;
}

PLIST_API plist_err_t plist_write_to_stream(plist_t plist, FILE *stream, plist_format_t format, plist_write_options_t options)
{
    if (!plist || !stream) {
        return PLIST_ERR_INVALID_ARG;
    }
    plist_err_t err = PLIST_ERR_UNKNOWN;
    char *output = NULL;
    uint32_t length = 0;
    switch (format) {
        case PLIST_FORMAT_BINARY:
            err = plist_to_bin(plist, &output, &length);
            break;
        case PLIST_FORMAT_XML:
            err = plist_to_xml(plist, &output, &length);
            break;
        case PLIST_FORMAT_JSON:
            err = plist_to_json(plist, &output, &length, ((options & PLIST_OPT_COMPACT) == 0));
            break;
        case PLIST_FORMAT_OSTEP:
            err = plist_to_openstep(plist, &output, &length, ((options & PLIST_OPT_COMPACT) == 0));
            break;
        case PLIST_FORMAT_PRINT:
            err = plist_write_to_stream_default(plist, stream, options);
            break;
        case PLIST_FORMAT_LIMD:
            err = plist_write_to_stream_limd(plist, stream, options);
            break;
        case PLIST_FORMAT_PLUTIL:
            err = plist_write_to_stream_plutil(plist, stream, options);
            break;
        default:
            // unsupported output format
            err = PLIST_ERR_FORMAT;
            break;
    }
    if (output && err == PLIST_ERR_SUCCESS) {
        if (fwrite(output, 1, length, stream) < length) {
            err = PLIST_ERR_IO;
        }
    }
    return err;
}

PLIST_API plist_err_t plist_write_to_file(plist_t plist, const char* filename, plist_format_t format, plist_write_options_t options)
{
    if (!plist || !filename) {
        return PLIST_ERR_INVALID_ARG;
    }
    FILE* f = fopen(filename, "wb");
    if (!f) {
        return PLIST_ERR_IO;
    }
    plist_err_t err = plist_write_to_stream(plist, f, format, options);
    fclose(f);
    return err;
}

PLIST_API void plist_print(plist_t plist)
{
     plist_write_to_stream(plist, stdout, PLIST_FORMAT_PRINT, PLIST_OPT_PARTIAL_DATA);
}
