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

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);
        g_node_destroy(plist);
    }
}

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

static char compare_node_value(plist_type type, plist_data_t data, const void *value, uint64_t length)
{
    char res = FALSE;
    switch (type)
    {
    case PLIST_BOOLEAN:
        res = data->boolval == *((char *) value) ? TRUE : FALSE;
        break;
    case PLIST_UINT:
        res = data->intval == *((uint64_t *) value) ? TRUE : FALSE;
        break;
    case PLIST_REAL:
        res = data->realval == *((double *) value) ? TRUE : FALSE;
        break;
    case PLIST_KEY:
    case PLIST_STRING:
        res = !strcmp(data->strval, ((char *) value));
        break;
    case PLIST_DATA:
        res = !memcmp(data->buff, (char *) value, length);
        break;
    case PLIST_DATE:
        res = !memcmp(&(data->timeval), value, sizeof(GTimeVal));
        break;
    case PLIST_ARRAY:
    case PLIST_DICT:
    default:
        break;
    }
    return res;
}

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 index = va_arg(v, uint32_t);
            current = plist_array_get_item(current, index);
        }
        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));
}

