/*
 * plist.c
 * Builds plist XML structures.
 *
 * 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
 */


#include <string.h>
#include <assert.h>
#include "plist.h"
#include <stdlib.h>
#include <stdio.h>

plist_t plist_new_node(plist_data_t data)
{
    return (plist_t) g_node_new(data);
}

plist_data_t plist_get_data(const plist_t node)
{
    if (!node)
        return NULL;
    return ((GNode *) 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 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;
        default:
            break;
        }
        free(data);
    }
}

static void plist_free_node(GNode * node, gpointer none)
{
    plist_data_t data = NULL;
    g_node_unlink(node);
    data = plist_get_data(node);
    plist_free_data(data);
    node->data = NULL;
    g_node_children_foreach(node, G_TRAVERSE_ALL, plist_free_node, NULL);
    g_node_destroy(node);
}

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_UINT;
    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->timeval.tv_sec = sec;
    data->timeval.tv_usec = usec;
    data->length = sizeof(GTimeVal);
    return plist_new_node(data);
}

void plist_free(plist_t plist)
{
    if (plist)
    {
        plist_free_node(plist, NULL);
    }
}

static void plist_copy_node(GNode * node, gpointer parent_node_ptr)
{
    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

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

    node_type = plist_get_node_type(node);
    if (node_type == PLIST_DATA || node_type == PLIST_STRING || node_type == PLIST_KEY)
    {
        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((char *) data->strval);
            break;
        default:
            break;
        }
    }
    newnode = plist_new_node(newdata);

    if (*(plist_t*)parent_node_ptr)
    {
        g_node_append(*(plist_t*)parent_node_ptr, newnode);
    }
    else
    {
        *(plist_t*)parent_node_ptr = newnode;
    }

    g_node_children_foreach(node, G_TRAVERSE_ALL, plist_copy_node, &newnode);
}

plist_t plist_copy(plist_t node)
{
    plist_t copied = NULL;
    plist_copy_node(node, &copied);
    return copied;
}

uint32_t plist_array_get_size(plist_t node)
{
    uint32_t ret = 0;
    if (node && PLIST_ARRAY == plist_get_node_type(node))
    {
        ret = g_node_n_children(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))
    {
        ret = (plist_t)g_node_nth_child(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 g_node_child_position(father, node);
    }
    return 0;
}

void plist_array_set_item(plist_t node, plist_t item, uint32_t n)
{
    if (node && PLIST_ARRAY == plist_get_node_type(node))
    {
        plist_t old_item = plist_array_get_item(node, n);
        if (old_item)
        {
            plist_free_node(old_item, NULL);
            old_item = NULL;
            plist_copy_node(item, &old_item);
        }
    }
    return;
}

void plist_array_append_item(plist_t node, plist_t item)
{
    if (node && PLIST_ARRAY == plist_get_node_type(node))
    {
        g_node_append(node, item);
    }
    return;
}

void plist_array_insert_item(plist_t node, plist_t item, uint32_t n)
{
    if (node && PLIST_ARRAY == plist_get_node_type(node))
    {
        g_node_insert(node, n, item);
    }
    return;
}

void plist_array_remove_item(plist_t node, uint32_t n)
{
    if (node && PLIST_ARRAY == plist_get_node_type(node))
    {
        plist_t old_item = plist_array_get_item(node, n);
        if (old_item)
        {
            plist_free(old_item);
        }
    }
    return;
}

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

void plist_dict_new_iter(plist_t node, plist_dict_iter *iter)
{
    if (iter && *iter == NULL)
    {
        *iter = malloc(sizeof(uint32_t));
        *((uint32_t*)(*iter)) = 0;
    }
    return;
}

void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val)
{
    uint32_t* iter_int = (uint32_t*) iter;

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

    if (node && PLIST_DICT == plist_get_node_type(node) && *iter_int < g_node_n_children(node))
    {

        if (key)
        {
            plist_get_key_val((plist_t)g_node_nth_child(node, *iter_int), key);
        }

        if (val)
        {
            *val = (plist_t) g_node_nth_child(node, *iter_int + 1);
        }

        *iter_int += 2;
    }
    return;
}

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

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_t current = NULL;
        for (current = (plist_t)g_node_first_child(node);
                current;
                current = (plist_t)g_node_next_sibling(g_node_next_sibling(current)))
        {

            plist_data_t data = plist_get_data(current);
            assert( PLIST_KEY == plist_get_node_type(current) );

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

void plist_dict_set_item(plist_t node, const char* key, plist_t item)
{
    if (node && PLIST_DICT == plist_get_node_type(node))
    {
        plist_t old_item = plist_dict_get_item(node, key);
        if (old_item)
        {
            plist_free_node(old_item, NULL);
            old_item = NULL;
            plist_copy_node(item, &old_item);
        }
    }
    return;
}

void plist_dict_insert_item(plist_t node, const char* key, plist_t item)
{
    if (node && PLIST_DICT == plist_get_node_type(node))
    {
        g_node_append(node, plist_new_key(key));
        g_node_append(node, item);
    }
    return;
}

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 = g_node_prev_sibling(old_item);
            plist_free(key_node);
            plist_free(old_item);
        }
    }
    return;
}

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_UINT:
        *((uint64_t *) value) = data->intval;
        break;
    case PLIST_REAL:
        *((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_DATE:
        //exception : here we use memory on the stack since it is just a temporary buffer
        ((GTimeVal *) value)->tv_sec = data->timeval.tv_sec;
        ((GTimeVal *) value)->tv_usec = data->timeval.tv_usec;
        break;
    case PLIST_ARRAY:
    case PLIST_DICT:
    default:
        break;
    }
}

plist_t plist_get_parent(plist_t node)
{
    return node ? (plist_t) ((GNode *) 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)
{
    plist_type type = plist_get_node_type(node);
    uint64_t length = 0;
    if (PLIST_KEY == type)
        plist_get_type_and_value(node, &type, (void *) val, &length);
    assert(length == strlen(*val));
}

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

void plist_get_bool_val(plist_t node, uint8_t * val)
{
    plist_type type = plist_get_node_type(node);
    uint64_t length = 0;
    if (PLIST_BOOLEAN == type)
        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)
{
    plist_type type = plist_get_node_type(node);
    uint64_t length = 0;
    if (PLIST_UINT == type)
        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)
{
    plist_type type = plist_get_node_type(node);
    uint64_t length = 0;
    if (PLIST_REAL == type)
        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)
{
    plist_type type = plist_get_node_type(node);
    if (PLIST_DATA == type)
        plist_get_type_and_value(node, &type, (void *) val, length);
}

void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec)
{
    plist_type type = plist_get_node_type(node);
    uint64_t length = 0;
    GTimeVal val = { 0, 0 };
    if (PLIST_DATE == type)
        plist_get_type_and_value(node, &type, (void *) &val, &length);
    assert(length == sizeof(GTimeVal));
    *sec = val.tv_sec;
    *usec = val.tv_usec;
}

gboolean plist_data_compare(gconstpointer a, gconstpointer b)
{
    plist_data_t val_a = NULL;
    plist_data_t val_b = NULL;

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

    if (!((GNode *) a)->data || !((GNode *) 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_UINT:
    case PLIST_REAL:
        if (val_a->intval == val_b->intval)	//it is an union so this is sufficient
            return TRUE;
        else
            return FALSE;

    case PLIST_KEY:
    case PLIST_STRING:
        if (!strcmp(val_a->strval, val_b->strval))
            return TRUE;
        else
            return FALSE;

    case PLIST_DATA:
        if (!memcmp(val_a->buff, val_b->buff, val_a->length))
            return TRUE;
        else
            return FALSE;
    case PLIST_ARRAY:
    case PLIST_DICT:
        //compare pointer
        if (a == b)
            return TRUE;
        else
            return FALSE;
        break;
    case PLIST_DATE:
        if (!memcmp(&(val_a->timeval), &(val_b->timeval), sizeof(GTimeVal)))
            return TRUE;
        else
            return FALSE;
    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_UINT:
        data->intval = *((uint64_t *) value);
        break;
    case PLIST_REAL:
        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_DATE:
        data->timeval.tv_sec = ((GTimeVal *) value)->tv_sec;
        data->timeval.tv_usec = ((GTimeVal *) value)->tv_usec;
        break;
    case PLIST_ARRAY:
    case PLIST_DICT:
    default:
        break;
    }
}

void plist_set_type(plist_t node, plist_type type)
{
    if ( g_node_n_children(node) == 0 )
    {
        plist_data_t data = plist_get_data(node);
        plist_free_data( data );
        data = plist_new_plist_data();
        data->type = type;
        switch (type)
        {
        case PLIST_BOOLEAN:
            data->length = sizeof(uint8_t);
            break;
        case PLIST_UINT:
            data->length = sizeof(uint64_t);
            break;
        case PLIST_REAL:
            data->length = sizeof(double);
            break;
        case PLIST_DATE:
            data->length = sizeof(GTimeVal);
            break;
        default:
            data->length = 0;
            break;
        }
    }
}

void plist_set_key_val(plist_t node, const char *val)
{
    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_UINT, &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)
{
    GTimeVal val = { sec, usec };
    plist_set_element_val(node, PLIST_DATE, &val, sizeof(GTimeVal));
}

