/****************************************************************************
**
** Copyright (C) 2015 Intel Corporation
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and associated documentation files (the "Software"), to deal
** in the Software without restriction, including without limitation the rights
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
** copies of the Software, and to permit persons to whom the Software is
** furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in
** all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
** THE SOFTWARE.
**
****************************************************************************/

#define _POSIX_C_SOURCE 200809L
#define _GNU_SOURCE
#include "cbor.h"
#include "cborinternal_p.h"
#include "compilersupport_p.h"

#include <cjson/cJSON.h>

#include <errno.h>
#include <math.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

static const char meta_data_marker[] = "$cbor";
uint8_t *buffer;
size_t buffersize;
bool usingMetaData = false;

struct MetaData {
    CborTag tag;
    union {
        const char *v;
        uint8_t simpleType;
    };
    CborType t;
    bool tagged;
};

uint8_t *decode_base64_generic(const char *string, size_t *len, const int8_t reverse_alphabet[256])
{
    *len = ((strlen(string) + 3) & ~3) * 3 / 4;
    uint8_t *buffer = malloc(*len);
    if (buffer == NULL)
        return NULL;

    uint8_t *out = buffer;
    const uint8_t *in = (const uint8_t *)string;
    bool done = false;
    while (!done) {
        if (reverse_alphabet[in[0]] < 0 || reverse_alphabet[in[1]] < 0) {
            if (in[0] == '\0')
                done = true;
            break;
        }

        uint32_t val = reverse_alphabet[in[0]] << 18;
        val |= reverse_alphabet[in[1]] << 12;
        if (in[2] == '=' || in[2] == '\0') {
            if (in[2] == '=' && (in[3] != '=' || in[4] != '\0'))
                break;
            val >>= 12;
            done = true;
        } else if (in[3] == '=' || in[3] == '\0') {
            if (in[3] == '=' && in[4] != '\0')
                break;
            val >>= 6;
            val |= reverse_alphabet[in[2]];
            done = true;
        } else {
            val |= reverse_alphabet[in[2]] << 6;
            val |= reverse_alphabet[in[3]];
        }

        *out++ = val >> 16;
        *out++ = val >> 8;
        *out++ = val;
        in += 4;
    }

    if (!done) {
        free(buffer);
        return NULL;
    }
    *len = out - buffer;
    return buffer;
}

uint8_t *decode_base64(const char *string, size_t *len)
{
    static const int8_t reverse_alphabet[256] = {
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
        52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
        -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
        -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
    };
    return decode_base64_generic(string, len, reverse_alphabet);
}

uint8_t *decode_base64url(const char *string, size_t *len)
{
    static const int8_t reverse_alphabet[256] = {
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1,
        52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
        -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63,
        -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
    };
    return decode_base64_generic(string, len, reverse_alphabet);
}

uint8_t *decode_base16(const char *string, size_t *len)
{
    size_t i;
    *len = strlen(string) / 2;
    uint8_t *buffer = malloc(*len);
    if (buffer == NULL)
        return NULL;

    for (i = 0; i < *len; ++i) {
        char c = string[i * 2];
        if (c >= '0' && c <= '9') {
            buffer[i] = (c - '0') << 4;
        } else if ((c | 0x20) >= 'a' && (c | 0x20) <= 'f') {
            buffer[i] = ((c | 0x20) - 'a' + 10) << 4;
        } else {
            free(buffer);
            return NULL;
        }

        c = string[i * 2 + 1];
        if (c >= '0' && c <= '9') {
            buffer[i] |= (c - '0');
        } else if ((c | 0x20) >= 'a' && (c | 0x20) <= 'f') {
            buffer[i] |= ((c | 0x20) - 'a' + 10);
        } else {
            free(buffer);
            return NULL;
        }
    }

    return buffer;
}

size_t get_cjson_size_limited(cJSON *container)
{
    // cJSON_GetArraySize is O(n), so don't go too far
    unsigned s = 0;
    cJSON *item;
    for (item = container->child; item; item = item->next) {
        if (++s > 255)
            return CborIndefiniteLength;
    }
    return s;
}

cJSON *get_meta_data(cJSON *object, cJSON *item)
{
    cJSON *meta;
    char *metadatakey;

    if (asprintf(&metadatakey, "%s%s", item->string, meta_data_marker) < 0 || metadatakey == NULL)
        return NULL;
    meta = cJSON_GetObjectItem(object, metadatakey);
    free(metadatakey);
    return meta;
}

struct MetaData parse_meta_data(cJSON *md)
{
    struct MetaData result = { 0, {NULL}, CborInvalidType, false };
    if (md == NULL || md->type != cJSON_Object)
        return result;

    for (md = md->child; md; md = md->next) {
        if (strcmp(md->string, "tag") == 0) {
            if (md->type != cJSON_String || sscanf(md->valuestring, "%" PRIu64, &result.tag) < 0)
                fprintf(stderr, "json2cbor: could not parse tag: %s\n", md->valuestring);
            else
                result.tagged = true;
        } else if (strcmp(md->string, "t") == 0) {
            result.t = md->valueint;
        } else if (strcmp(md->string, "v") == 0) {
            if (md->type == cJSON_Number)
                result.simpleType = md->valueint;
            else
                result.v = md->valuestring;
        }
    }
    return result;
}

CborError decode_json(cJSON *json, CborEncoder *encoder);
CborError decode_json_with_metadata(cJSON *item, CborEncoder *encoder, struct MetaData md)
{
    switch (md.t) {
    case CborIntegerType: {
        // integer that has more than 53 bits of precision
        uint64_t v;
        bool positive = *md.v++ == '+';
        if (sscanf(md.v, "%" PRIx64, &v) < 0) {
            fprintf(stderr, "json2cbor: could not parse number: %s\n", md.v);
            break;
        }
        return positive ? cbor_encode_uint(encoder, v) : cbor_encode_negative_int(encoder, v);
    }

    case CborByteStringType: {
        uint8_t *data;
        size_t len;
        if (md.tag == CborExpectedBase64Tag)
            data = decode_base64(item->valuestring, &len);
        else if (md.tag == CborExpectedBase16Tag)
            data = decode_base16(item->valuestring, &len);
        else if (md.tag == CborNegativeBignumTag)
            data = decode_base64url(item->valuestring + 1, &len);
        else
            data = decode_base64url(item->valuestring, &len);

        if (data != NULL) {
            CborError err = cbor_encode_byte_string(encoder, data, len);
            free(data);
            return err;
        }
        fprintf(stderr, "json2cbor: could not decode encoded byte string: %s\n", item->valuestring);
        break;
    }

    case CborSimpleType:
        return cbor_encode_simple_value(encoder, md.simpleType);

    case CborUndefinedType:
        return cbor_encode_undefined(encoder);

    case CborHalfFloatType:
    case CborFloatType:
    case CborDoubleType: {
        unsigned short half;
        double v;
        if (!md.v) {
            v = item->valuedouble;
        } else if (strcmp(md.v, "nan") == 0) {
            v = NAN;
        } else if (strcmp(md.v, "-inf") == 0) {
            v = -INFINITY;
        } else if (strcmp(md.v, "inf") == 0) {
            v = INFINITY;
        } else {
            fprintf(stderr, "json2cbor: invalid floating-point value: %s\n", md.v);
            break;
        }

        // we can't get an OOM here because the metadata makes up for space
        // (the smallest metadata is "$cbor":{"t":250} (17 bytes)
        return (md.t == CborDoubleType) ? cbor_encode_double(encoder, v) :
               (md.t == CborFloatType) ? cbor_encode_float(encoder, v) :
                                         (half = encode_half(v), cbor_encode_half_float(encoder, &half));
    }

    default:
        fprintf(stderr, "json2cbor: invalid CBOR type: %d\n", md.t);
    case CborInvalidType:
        break;
    }

    return decode_json(item, encoder);
}

CborError decode_json(cJSON *json, CborEncoder *encoder)
{
    CborEncoder container;
    CborError err;
    cJSON *item;

    switch (json->type) {
    case cJSON_False:
    case cJSON_True:
        return cbor_encode_boolean(encoder, json->type == cJSON_True);

    case cJSON_NULL:
        return cbor_encode_null(encoder);

    case cJSON_Number:
        if ((double)json->valueint == json->valuedouble)
            return cbor_encode_int(encoder, json->valueint);
encode_double:
        // the only exception that JSON is larger: floating point numbers
        container = *encoder;   // save the state
        err = cbor_encode_double(encoder, json->valuedouble);

        if (err == CborErrorOutOfMemory) {
            buffersize += 1024;
            uint8_t *newbuffer = realloc(buffer, buffersize);
            if (newbuffer == NULL)
                return err;

            *encoder = container;   // restore state
            encoder->data.ptr = newbuffer + (container.data.ptr - buffer);
            encoder->end = newbuffer + buffersize;
            buffer = newbuffer;
            goto encode_double;
        }
        return err;

    case cJSON_String:
        return cbor_encode_text_stringz(encoder, json->valuestring);

    default:
        return CborErrorUnknownType;

    case cJSON_Array:
        err = cbor_encoder_create_array(encoder, &container, get_cjson_size_limited(json));
        if (err)
            return err;
        for (item = json->child; item; item = item->next) {
            err = decode_json(item, &container);
            if (err)
                return err;
        }
        return cbor_encoder_close_container_checked(encoder, &container);

    case cJSON_Object:
        err = cbor_encoder_create_map(encoder, &container,
                                      usingMetaData ? CborIndefiniteLength : get_cjson_size_limited(json));
        if (err)
            return err;

        for (item = json->child ; item; item = item->next) {
            if (usingMetaData && strlen(item->string) > strlen(meta_data_marker)
                    && strcmp(item->string + strlen(item->string) - strlen(meta_data_marker), meta_data_marker) == 0)
                continue;

            err = cbor_encode_text_stringz(&container, item->string);
            if (err)
                return err;

            if (usingMetaData) {
                cJSON *meta = get_meta_data(json, item);
                struct MetaData md = parse_meta_data(meta);
                if (md.tagged) {
                    err = cbor_encode_tag(&container, md.tag);
                    if (err)
                        return err;
                }

                err = decode_json_with_metadata(item, &container, md);
            } else {
                err = decode_json(item, &container);
            }
            if (err)
                return err;
        }

        return cbor_encoder_close_container_checked(encoder, &container);
    }
}

int main(int argc, char **argv)
{
    int c;
    while ((c = getopt(argc, argv, "M")) != -1) {
        switch (c) {
        case 'M':
            usingMetaData = true;
            break;

        case '?':
            fprintf(stderr, "Unknown option -%c.\n", optopt);
            // fall through
        case 'h':
            puts("Usage: json2cbor [OPTION]... [FILE]...\n"
                 "Reads JSON content from FILE and converts to CBOR.\n"
                 "\n"
                 "Options:\n"
                 " -M       Interpret metadata added by cbordump tool\n"
                 "");
            return c == '?' ? EXIT_FAILURE : EXIT_SUCCESS;
        }
    }

    FILE *in;
    const char *fname = argv[optind];
    if (fname && strcmp(fname, "-") != 0) {
        in = fopen(fname, "r");
        if (!in) {
            perror("open");
            return EXIT_FAILURE;
        }
    } else {
        in = stdin;
        fname = "-";
    }

    /* 1. read the file */
    off_t fsize;
    if (fseeko(in, 0, SEEK_END) == 0 && (fsize = ftello(in)) >= 0) {
        buffersize = fsize + 1;
        buffer = malloc(buffersize);
        if (buffer == NULL) {
            perror("malloc");
            return EXIT_FAILURE;
        }

        rewind(in);
        fsize = fread(buffer, 1, fsize, in);
        buffer[fsize] = '\0';
    } else {
        const unsigned chunk = 16384;
        buffersize = 0;
        buffer = NULL;
        do {    // it the hard way
            buffer = realloc(buffer, buffersize + chunk);
            if (buffer == NULL) {
                perror("malloc");
                return EXIT_FAILURE;
            }

            buffersize += fread(buffer + buffersize, 1, chunk, in);
        } while (!feof(in) && !ferror(in));
        buffer[buffersize] = '\0';
    }

    if (ferror(in)) {
        perror("read");
        return EXIT_FAILURE;
    }
    if (in != stdin)
        fclose(in);

    /* 2. parse as JSON */
    cJSON *doc = cJSON_ParseWithOpts((char *)buffer, NULL, true);
    if (doc == NULL) {
        fprintf(stderr, "json2cbor: %s: could not parse.\n", fname);
        return EXIT_FAILURE;
    }

    /* 3. encode as CBOR */
    // We're going to reuse the buffer, as CBOR is usually shorter than the equivalent JSON
    CborEncoder encoder;
    cbor_encoder_init(&encoder, buffer, buffersize, 0);
    CborError err = decode_json(doc, &encoder);

    cJSON_Delete(doc);

    if (err) {
        fprintf(stderr, "json2cbor: %s: error encoding to CBOR: %s\n", fname,
                cbor_error_string(err));
        return EXIT_FAILURE;
    }

    fwrite(buffer, 1, encoder.data.ptr - buffer, stdout);
    free(buffer);
    return EXIT_SUCCESS;
}
