/*
 * 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>

#ifdef _MSC_VER
typedef SSIZE_T ssize_t;
#endif

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

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_err_t plist_from_memory(const char *plist_data, uint32_t length, plist_t *plist, plist_format_t *format)
{
    plist_err_t res = PLIST_ERR_UNKNOWN;
    if (!plist) {
        return PLIST_ERR_INVALID_ARG;
    }
    *plist = NULL;
    if (!plist_data || length == 0) {
        return PLIST_ERR_INVALID_ARG;
    }
    plist_format_t fmt = PLIST_FORMAT_NONE;
    if (format) *format = PLIST_FORMAT_NONE;
    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 (pos >= length) {
            return PLIST_ERR_PARSE;
        }
        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 (pos >= length) {
                return PLIST_ERR_PARSE;
            }
            if (plist_data[pos] == '"') {
                /* still could be both */
                pos++;
                while (pos < length) {
                    FIND_NEXT(plist_data, pos, length, '"');
                    if (plist_data[pos-1] != '\\') {
                        break;
                    }
                    pos++;
                }
                if (pos >= length) {
                    return PLIST_ERR_PARSE;
                }
                if (plist_data[pos] == '"') {
                    pos++;
                    SKIP_WS(plist_data, pos, length);
                    if (pos >= length) {
                        return PLIST_ERR_PARSE;
                    }
                    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_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 ((uint64_t)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 = (char*)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 (plist_data_t)((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((ptrarray_t*)data->hashtable);
            break;
        case PLIST_DICT:
            hash_table_destroy((hashtable_t*)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_t plist_new_dict(void)
{
    plist_data_t data = plist_new_plist_data();
    data->type = PLIST_DICT;
    return plist_new_node(data);
}

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_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_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_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_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_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_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_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_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_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);
}

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

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((node_t)newnode, (node_t)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_t plist_copy(plist_t node)
{
    return node ? plist_copy_node((node_t)node) : NULL;
}

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_t)node);
    }
    return ret;
}

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 = (ptrarray_t*)((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_t)node, n);
        }
    }
    return ret;
}

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((node_t)father, (node_t)node);
    }
    return UINT_MAX;
}

static void _plist_array_post_insert(plist_t node, plist_t item, long n)
{
    ptrarray_t *pa = (ptrarray_t*)((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_t)node);
                 pa && current;
                 current = (plist_t)node_next_sibling((node_t)current))
            {
                ptr_array_add(pa, current);
            }
            ((plist_data_t)((node_t)node)->data)->hashtable = pa;
        }
    }
}

void plist_array_set_item(plist_t node, plist_t item, uint32_t n)
{
    if (!item) {
        return;
    }
    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((node_t)old_item);
            assert(idx >= 0);
            if (idx < 0) {
                return;
            }
            node_insert((node_t)node, idx, (node_t)item);
            ptrarray_t* pa = (ptrarray_t*)((plist_data_t)((node_t)node)->data)->hashtable;
            if (pa) {
                ptr_array_set(pa, item, idx);
            }
        }
    }
}

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

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

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 = (ptrarray_t*)((plist_data_t)((node_t)node)->data)->hashtable;
            if (pa) {
                ptr_array_remove(pa, n);
            }
            plist_free(old_item);
        }
    }
}

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((node_t)father, (node_t)node);
        if (n < 0) return;
        ptrarray_t* pa = (ptrarray_t*)((plist_data_t)((node_t)father)->data)->hashtable;
        if (pa) {
            ptr_array_remove(pa, n);
        }
        plist_free(node);
    }
}

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_t)node);
    }
}

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);
    }
}

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_t)node) / 2;
    }
    return ret;
}

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_t)node);
    }
}

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);
    }
}

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_t)node), key);
    }
}

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_t)node);
    }
    return ret;
}

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_t)node);
                current;
                current = (plist_t)node_next_sibling(node_next_sibling((node_t)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((node_t)current);
                    break;
                }
            }
        }
    }
    return ret;
}

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

        hashtable_t *ht = (hashtable_t*)((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_t)node);
                     ht && current;
                     current = (plist_t)node_next_sibling(node_next_sibling((node_t)current)))
                {
                    hash_table_insert(ht, ((node_t)current)->data, node_next_sibling((node_t)current));
                }
                ((plist_data_t)((node_t)node)->data)->hashtable = ht;
            }
        }
    }
}

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((node_t)old_item);
            hashtable_t* ht = (hashtable_t*)((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);
        }
    }
}

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_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_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_t plist_get_parent(plist_t node)
{
    return node ? (plist_t) ((node_t) node)->parent : NULL;
}

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;
}

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));
}

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));
}

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;
}

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));
}

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);
}

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

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));
}

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));
}

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);
}

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;
}

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;
}

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;
    }
}

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));
}

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

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

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));
}

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

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

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

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

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));
}

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);
}

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;
}

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;
}

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;
}

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;
}

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;
}

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;
}

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);
}

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);
}

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);
}

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);
}

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);
}

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);
}

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);
}

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);
}

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);

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);
}

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_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_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;
        }
        free(output);
    }
    return err;
}

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;
}

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