/*
 * out-default.c
 * libplist default *output-only* format - NOT for machine parsing
 *
 * Copyright (c) 2022-2023 Nikias Bassen 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

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

#include <inttypes.h>
#include <ctype.h>
#include <math.h>
#include <limits.h>

#include <node.h>

#include "plist.h"
#include "strbuf.h"
#include "time64.h"
#include "hashtable.h"
#include "common.h"

static plist_err_t node_to_string(node_t node, bytearray_t **outbuf, uint32_t depth, uint32_t indent, int partial_data)
{
    plist_data_t node_data = NULL;

    char *val = NULL;
    int slen = 0;
    size_t val_len = 0;

    uint32_t i = 0;

    if (!node || !outbuf || !*outbuf) {
        return PLIST_ERR_INVALID_ARG;
    }

    node_data = plist_get_data(node);
    if (!node_data) {
        return PLIST_ERR_INVALID_ARG;
    }

    switch (node_data->type)
    {
    case PLIST_BOOLEAN:
    {
        if (node_data->boolval) {
            str_buf_append(*outbuf, "true", 4);
        } else {
            str_buf_append(*outbuf, "false", 5);
        }
    }
    break;

    case PLIST_NULL:
        str_buf_append(*outbuf, "null", 4);
	break;

    case PLIST_INT:
        val = (char*)malloc(64);
        if (!val) return PLIST_ERR_NO_MEM;
        if (node_data->length == 16) {
            slen = snprintf(val, 64, "%" PRIu64, node_data->intval);
        } else {
            slen = snprintf(val, 64, "%" PRIi64, node_data->intval);
        }
        if (slen < 0) {
            free(val);
            return PLIST_ERR_UNKNOWN;
        }
        val_len = (size_t)slen;
        str_buf_append(*outbuf, val, val_len);
        free(val);
        break;

    case PLIST_REAL:
        val = (char*)malloc(64);
        if (!val) return PLIST_ERR_NO_MEM;
        val_len = dtostr(val, 64, node_data->realval);
        str_buf_append(*outbuf, val, val_len);
        free(val);
        break;

    case PLIST_STRING:
    case PLIST_KEY: {
        if (!node_data->strval && node_data->length > 0) {
            return PLIST_ERR_INVALID_ARG;
        }
        const char *charmap[32] = {
            "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", "\\u0006", "\\u0007",
            "\\b",     "\\t",     "\\n",     "\\u000b", "\\f",     "\\r",     "\\u000e", "\\u000f",
            "\\u0010", "\\u0011", "\\u0012", "\\u0013", "\\u0014", "\\u0015", "\\u0016", "\\u0017",
            "\\u0018", "\\u0019", "\\u001a", "\\u001b", "\\u001c", "\\u001d", "\\u001e", "\\u001f",
        };
        size_t j = 0;
        size_t len = 0;
        size_t start = 0;
        size_t cur = 0;

        str_buf_append(*outbuf, "\"", 1);

        len = node_data->length;
        for (j = 0; j < len; j++) {
            unsigned char ch = (unsigned char)node_data->strval[j];
            if (ch < 0x20) {
                str_buf_append(*outbuf, node_data->strval + start, cur - start);
                str_buf_append(*outbuf, charmap[ch], (charmap[ch][1] == 'u') ? 6 : 2);
                start = cur+1;
            } else if (ch == '"') {
                str_buf_append(*outbuf, node_data->strval + start, cur - start);
                str_buf_append(*outbuf, "\\\"", 2);
                start = cur+1;
            }
            cur++;
        }
        str_buf_append(*outbuf, node_data->strval + start, cur - start);

        str_buf_append(*outbuf, "\"", 1);
        } break;

    case PLIST_ARRAY: {
        str_buf_append(*outbuf, "[", 1);
        node_t ch;
        uint32_t cnt = 0;
        for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) {
            if (cnt > 0) {
                str_buf_append(*outbuf, ",", 1);
            }
            str_buf_append(*outbuf, "\n", 1);
            for (i = 0; i <= depth+indent; i++) {
                str_buf_append(*outbuf, "  ", 2);
            }
            plist_err_t res = node_to_string(ch, outbuf, depth+1, indent, partial_data);
            if (res < 0) {
                return res;
            }
            cnt++;
        }
        if (cnt > 0) {
            str_buf_append(*outbuf, "\n", 1);
            for (i = 0; i < depth+indent; i++) {
                str_buf_append(*outbuf, "  ", 2);
            }
        }
        str_buf_append(*outbuf, "]", 1);
        } break;
    case PLIST_DICT: {
        str_buf_append(*outbuf, "{", 1);
        node_t ch;
        uint32_t cnt = 0;
        for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) {
            if (cnt > 0 && cnt % 2 == 0) {
                str_buf_append(*outbuf, ",", 1);
            }
            if (cnt % 2 == 0) {
                str_buf_append(*outbuf, "\n", 1);
                for (i = 0; i <= depth+indent; i++) {
                    str_buf_append(*outbuf, "  ", 2);
                }
            }
            plist_err_t res = node_to_string(ch, outbuf, depth+1, indent, partial_data);
            if (res < 0) {
                return res;
            }
            if (cnt % 2 == 0) {
                str_buf_append(*outbuf, ": ", 2);
            }
            cnt++;
        }
        if (cnt > 0) {
            str_buf_append(*outbuf, "\n", 1);
            for (i = 0; i < depth+indent; i++) {
                str_buf_append(*outbuf, "  ", 2);
            }
        }
        str_buf_append(*outbuf, "}", 1);
        } break;
    case PLIST_DATA:
        {
            if (!node_data->buff && node_data->length > 0) {
                return PLIST_ERR_INVALID_ARG;
            }
            str_buf_append(*outbuf, "<", 1);
            size_t len = node_data->length;
            char charb[4];
            size_t j;
            if (!partial_data || len <= 24) {
                for (j = 0; j < len; j++) {
                    if (j > 0 && (j % 4 == 0))
                        str_buf_append(*outbuf, " ", 1);
                    snprintf(charb, sizeof(charb), "%02x", (unsigned char)node_data->buff[j]);
                    str_buf_append(*outbuf, charb, 2);
                }
            } else {
                for (j = 0; j < 16; j++) {
                    if (j > 0 && (j % 4 == 0))
                        str_buf_append(*outbuf, " ", 1);
                    snprintf(charb, sizeof(charb), "%02x", (unsigned char)node_data->buff[j]);
                    str_buf_append(*outbuf, charb, 2);
                }
                str_buf_append(*outbuf, " ... ", 5);
                for (j = len - 8; j < len; j++) {
                    snprintf(charb, sizeof(charb), "%02x", (unsigned char)node_data->buff[j]);
                    str_buf_append(*outbuf, charb, 2);
                    if (j > 0 && j < len-1 && (j % 4 == 0))
                        str_buf_append(*outbuf, " ", 1);
                }
            }
            str_buf_append(*outbuf, ">", 1);
        }
        break;
    case PLIST_DATE:
        {
            Time64_T timev;
            if (plist_real_to_time64(node_data->realval, &timev) < 0) {
#if DEBUG
                fprintf(stderr, "libplist: ERROR: Encountered invalid date value %f\n", node_data->realval);
#endif
                return PLIST_ERR_INVALID_ARG;
            }
            struct TM _btime;
            struct TM *btime = gmtime64_r(&timev, &_btime);
            if (btime) {
                val = (char*)calloc(1, 26);
                if (!val) return PLIST_ERR_NO_MEM;
                struct tm _tmcopy;
                copy_TM64_to_tm(btime, &_tmcopy);
                val_len = strftime(val, 26, "%Y-%m-%d %H:%M:%S +0000", &_tmcopy);
                if (val_len > 0) {
                    str_buf_append(*outbuf, val, val_len);
                }
                free(val);
                val = NULL;
            }
        }
        break;
    case PLIST_UID:
        {
            str_buf_append(*outbuf, "CF$UID:", 7);
            val = (char*)malloc(64);
            if (!val) return PLIST_ERR_NO_MEM;
            if (node_data->length == 16) {
                slen = snprintf(val, 64, "%" PRIu64, node_data->intval);
            } else {
                slen = snprintf(val, 64, "%" PRIi64, node_data->intval);
            }
            if (slen < 0) {
                free(val);
                return PLIST_ERR_UNKNOWN;
            }
            val_len = (size_t)slen;
            str_buf_append(*outbuf, val, val_len);
            free(val);
        }
        break;
    default:
        return PLIST_ERR_UNKNOWN;
    }

    return PLIST_ERR_SUCCESS;
}

static plist_err_t _node_estimate_size(node_t node, uint64_t *size, uint32_t depth, uint32_t indent, int partial_data, hashtable_t *visited)
{
    plist_data_t data;
    if (!node) {
        return PLIST_ERR_INVALID_ARG;
    }

    if (depth > PLIST_MAX_NESTING_DEPTH) {
#if DEBUG
        fprintf(stderr, "libplist: ERROR: maximum nesting depth (%u) exceeded\n", (unsigned)PLIST_MAX_NESTING_DEPTH);
#endif
        return PLIST_ERR_MAX_NESTING;
    }

    if (hash_table_lookup(visited, node)) {
#if DEBUG
        fprintf(stderr, "libplist: ERROR: circular reference detected\n");
#endif
        return PLIST_ERR_CIRCULAR_REF;
    }

    // mark as visited
    hash_table_insert(visited, node, (void*)1);

    data = plist_get_data(node);
    if (node->children) {
        node_t ch;
        unsigned int n_children = node_n_children(node);
        for (ch = node_first_child(node); ch; ch = node_next_sibling(ch)) {
            plist_err_t res = _node_estimate_size(ch, size, depth + 1, indent, partial_data, visited);
            if (res != PLIST_ERR_SUCCESS) {
                return res;
            }
        }
        switch (data->type) {
        case PLIST_DICT:
            *size += 2; // '{' and '}'
            *size += n_children-1; // number of ':' and ','
            *size += n_children; // number of '\n' and extra space
            *size += (uint64_t)n_children * (depth+indent+1); // indent for every 2nd child
            *size += indent+1; // additional '\n'
            break;
        case PLIST_ARRAY:
            *size += 2; // '[' and ']'
            *size += n_children-1; // number of ','
            *size += n_children; // number of '\n'
            *size += (uint64_t)n_children * ((depth+indent+1)<<1); // indent for every child
            *size += indent+1; // additional '\n'
            break;
        default:
            break;
	}
        *size += ((depth+indent) << 1); // indent for {} and []
    } else {
        switch (data->type) {
        case PLIST_STRING:
        case PLIST_KEY:
            *size += data->length;
            *size += 2;
            break;
        case PLIST_INT:
            if (data->length == 16) {
                *size += num_digits_u(data->intval);
            } else {
                *size += num_digits_i((int64_t)data->intval);
            }
            break;
        case PLIST_REAL:
            *size += dtostr(NULL, 0, data->realval);
            break;
        case PLIST_BOOLEAN:
            *size += ((data->boolval) ? 4 : 5);
            break;
        case PLIST_NULL:
            *size += 4;
            break;
        case PLIST_DICT:
        case PLIST_ARRAY:
            *size += 2;
            break;
        case PLIST_DATA:
            *size += 2; // < and >
            if (partial_data) {
                *size += 58;
            } else {
                *size += data->length * 2;
                *size += data->length / 4; // space between 4 byte groups
            }
            break;
        case PLIST_DATE:
            *size += 25;
            break;
        case PLIST_UID:
            *size += 7; // "CF$UID:"
            *size += num_digits_u(data->intval);
            break;
        default:
#ifdef DEBUG
            fprintf(stderr, "%s: invalid node type encountered\n", __func__);
#endif
            return PLIST_ERR_UNKNOWN;
        }
    }
    if (depth == 0) {
        *size += 1; // final newline
    }
    return PLIST_ERR_SUCCESS;
}

static plist_err_t node_estimate_size(node_t node, uint64_t *size, uint32_t depth, uint32_t indent, int partial_data)
{
    hashtable_t *visited = hash_table_new(plist_node_ptr_hash, plist_node_ptr_compare, NULL);
    if (!visited) return PLIST_ERR_NO_MEM;
    plist_err_t err = _node_estimate_size(node, size, depth, indent, partial_data, visited);
    hash_table_destroy(visited);
    return err;
}

static plist_err_t _plist_write_to_strbuf(plist_t plist, strbuf_t *outbuf, plist_write_options_t options)
{
    uint8_t indent = 0;
    if (options & PLIST_OPT_INDENT) {
        indent = (options >> 24) & 0xFF;
    }
    uint8_t i;
    for (i = 0; i < indent; i++) {
        str_buf_append(outbuf, "  ", 2);
    }
    plist_err_t res = node_to_string((node_t)plist, &outbuf, 0, indent, options & PLIST_OPT_PARTIAL_DATA);
    if (res < 0) {
        return res;
    }
    if (!(options & PLIST_OPT_NO_NEWLINE)) {
        str_buf_append(outbuf, "\n", 1);
    }
    return res;
}

plist_err_t plist_write_to_string_default(plist_t plist, char **output, uint32_t* length, plist_write_options_t options)
{
    uint64_t size = 0;
    plist_err_t res;

    if (!plist || !output || !length) {
        return PLIST_ERR_INVALID_ARG;
    }

    uint8_t indent = 0;
    if (options & PLIST_OPT_INDENT) {
        indent = (options >> 24) & 0xFF;
    }

    res = node_estimate_size((node_t)plist, &size, 0, indent, options & PLIST_OPT_PARTIAL_DATA);
    if (res < 0) {
        return res;
    }

    strbuf_t *outbuf = str_buf_new(size);
    if (!outbuf) {
#if DEBUG
        fprintf(stderr, "%s: Could not allocate output buffer\n", __func__);
#endif
        return PLIST_ERR_NO_MEM;
    }

    res = _plist_write_to_strbuf(plist, outbuf, options);
    if (res < 0) {
        str_buf_free(outbuf);
        *output = NULL;
        *length = 0;
        return res;
    }
    str_buf_append(outbuf, "\0", 1);

    if (!outbuf->data) {
        str_buf_free(outbuf);
        *output = NULL;
        *length = 0;
        return PLIST_ERR_NO_MEM;
    }

    *output = (char*)outbuf->data;
    *length = outbuf->len - 1;

    outbuf->data = NULL;
    str_buf_free(outbuf);

    return PLIST_ERR_SUCCESS;
}

plist_err_t plist_write_to_stream_default(plist_t plist, FILE *stream, plist_write_options_t options)
{
    if (!plist || !stream) {
        return PLIST_ERR_INVALID_ARG;
    }
    strbuf_t *outbuf = str_buf_new_for_stream(stream);
    if (!outbuf) {
#if DEBUG
        fprintf(stderr, "%s: Could not allocate output buffer\n", __func__);
#endif
        return PLIST_ERR_NO_MEM;
    }

    plist_err_t res = _plist_write_to_strbuf(plist, outbuf, options);
    if (res < 0) {
        str_buf_free(outbuf);
        return res;
    }

    str_buf_free(outbuf);

    return PLIST_ERR_SUCCESS;
}
