/****************************************************************************
**
** Copyright (C) 2016 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 _BSD_SOURCE 1
#define _DEFAULT_SOURCE 1
#define _GNU_SOURCE 1
#define _POSIX_C_SOURCE 200809L
#ifndef __STDC_LIMIT_MACROS
#  define __STDC_LIMIT_MACROS 1
#endif

#include "cbor.h"
#include "cborjson.h"
#include "compilersupport_p.h"

#include <float.h>
#include <inttypes.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/**
 * \defgroup CborToJson Converting CBOR to JSON
 * \brief Group of functions used to convert CBOR to JSON.
 *
 * This group contains two functions that are can be used to convert one
 * CborValue object to an equivalent JSON representation. This module attempts
 * to follow the recommendations from RFC 7049 section 4.1 "Converting from
 * CBOR to JSON", though it has a few differences. They are noted below.
 *
 * These functions produce a "minified" JSON output, with no spacing,
 * indentation or line breaks. If those are necessary, they need to be applied
 * in a post-processing phase.
 *
 * Note that JSON cannot support all CBOR types with fidelity, so the
 * conversion is usually lossy. For that reason, TinyCBOR supports adding a set
 * of metadata JSON values that can be used by a JSON-to-CBOR converter to
 * restore the original data types.
 *
 * The TinyCBOR library does not provide a way to convert from JSON
 * representation back to encoded form. However, it provides a tool called
 * \c json2cbor which can be used for that purpose. That tool supports the
 * metadata format that these functions may produce.
 *
 * Either of the functions in this section will attempt to convert exactly one
 * CborValue object to JSON. Those functions may return any error documented
 * for the functions for CborParsing. In addition, if the C standard library
 * stream functions return with error, the text conversion will return with
 * error CborErrorIO.
 *
 * These functions also perform UTF-8 validation in CBOR text strings. If they
 * encounter a sequence of bytes that not permitted in UTF-8, they will return
 * CborErrorInvalidUtf8TextString. That includes encoding of surrogate points
 * in UTF-8.
 *
 * \warning The metadata produced by these functions is not guaranteed to
 * remain stable. A future update of TinyCBOR may produce different output for
 * the same input and parsers may be unable to handle them.
 *
 * \sa CborParsing, CborPretty, cbor_parser_init()
 */

/**
 * \addtogroup CborToJson
 * @{
 * <h2 class="groupheader">Conversion limitations</h2>
 *
 * When converting from CBOR to JSON, there may be information loss. This
 * section lists the possible scenarios.
 *
 * \par Number precision:
 * ALL JSON numbers, due to its JavaScript heritage, are IEEE 754
 * double-precision floating point. This means JSON is not capable of
 * representing integers numbers outside the range [-(2<sup>53</sup>)+1,
 * 2<sup>53</sup>-1] and is not capable of representing NaN or infinite. If the
 * CBOR data contains a number outside the valid range, the conversion will
 * lose precision. If the input was NaN or infinite, the result of the
 * conversion will be "null". In addition, the distinction between half-,
 * single- and double-precision is lost.
 *
 * \par
 * If enabled, the original value and original type are stored in the metadata.
 *
 * \par Non-native types:
 * CBOR's type system is richer than JSON's, which means some data values
 * cannot be represented when converted to JSON. The conversion silently turns
 * them into strings: CBOR simple types become "simple(nn)" where \c nn is the
 * simple type's value, with the exception of CBOR undefined, which becomes
 * "undefined", while CBOR byte strings are converted to an Base16, Base64, or
 * Base64url encoding
 *
 * \par
 * If enabled, the original type is stored in the metadata.
 *
 * \par Presence of tags:
 * JSON has no support for tagged values, so by default tags are dropped when
 * converting to JSON. However, if the CborConvertObeyByteStringTags option is
 * active (default), then certain known tags are honored and are used to format
 * the conversion of the tagged byte string to JSON.
 *
 * \par
 * If the CborConvertTagsToObjects option is active, then the tag and the
 * tagged value are converted to to a JSON object. Otherwise, if enabled, the
 * last (innermost) tag is stored in the metadata.
 *
 * \par Non-string keys in maps:
 * JSON requires all Object keys to be strings, while CBOR does not. By
 * default, if a non-string key is found, the conversion fails with error
 * CborErrorJsonObjectKeyNotString. If the CborConvertStringifyMapKeys option
 * is active, then the conversion attempts to create a string representation
 * using CborPretty. Note that the \c json2cbor tool is not able to parse this
 * back to the original form.
 *
 * \par Duplicate keys in maps:
 * Neither JSON nor CBOR allow duplicated keys, but current TinyCBOR does not
 * validate that this is the case. If there are duplicated keys in the input,
 * they will be repeated in the output, which may JSON tools may flag as
 * invalid. In addition to that, if the CborConvertStringifyMapKeys option is
 * active, it is possible that a non-string key in a CBOR map will be converted
 * to a string form that is identical to another key.
 *
 * \par
 * When metadata support is active, the conversion will add extra key-value
 * pairs to the JSON output so it can store the metadata. It is possible that
 * the keys for the metadata clash with existing keys in the JSON map.
 */

extern FILE *open_memstream(char **bufptr, size_t *sizeptr);

enum ConversionStatusFlags {
    TypeWasNotNative            = 0x100,    /* anything but strings, boolean, null, arrays and maps */
    TypeWasTagged               = 0x200,
    NumberPrecisionWasLost      = 0x400,
    NumberWasNaN                = 0x800,
    NumberWasInfinite           = 0x1000,
    NumberWasNegative           = 0x2000,   /* always used with NumberWasInifite or NumberWasTooBig */

    FinalTypeMask               = 0xff
};

typedef struct ConversionStatus {
    CborTag lastTag;
    uint64_t originalNumber;
    int flags;
} ConversionStatus;

static CborError value_to_json(FILE *out, CborValue *it, int flags, CborType type, ConversionStatus *status);

static CborError dump_bytestring_base16(char **result, CborValue *it)
{
    static const char characters[] = "0123456789abcdef";
    size_t i;
    size_t n = 0;
    uint8_t *buffer;
    CborError err = cbor_value_calculate_string_length(it, &n);
    if (err)
        return err;

    /* a Base16 (hex) output is twice as big as our buffer */
    buffer = (uint8_t *)malloc(n * 2 + 1);
    *result = (char *)buffer;

    /* let cbor_value_copy_byte_string know we have an extra byte for the terminating NUL */
    ++n;
    err = cbor_value_copy_byte_string(it, buffer + n - 1, &n, it);
    cbor_assert(err == CborNoError);

    for (i = 0; i < n; ++i) {
        uint8_t byte = buffer[n + i];
        buffer[2*i]     = characters[byte >> 4];
        buffer[2*i + 1] = characters[byte & 0xf];
    }
    return CborNoError;
}

static CborError generic_dump_base64(char **result, CborValue *it, const char alphabet[65])
{
    size_t n = 0, i;
    uint8_t *buffer, *out, *in;
    CborError err = cbor_value_calculate_string_length(it, &n);
    if (err)
        return err;

    /* a Base64 output (untruncated) has 4 bytes for every 3 in the input */
    size_t len = (n + 5) / 3 * 4;
    out = buffer = (uint8_t *)malloc(len + 1);
    *result = (char *)buffer;

    /* we read our byte string at the tail end of the buffer
     * so we can do an in-place conversion while iterating forwards */
    in = buffer + len - n;

    /* let cbor_value_copy_byte_string know we have an extra byte for the terminating NUL */
    ++n;
    err = cbor_value_copy_byte_string(it, in, &n, it);
    cbor_assert(err == CborNoError);

    uint_least32_t val = 0;
    for (i = 0; n - i >= 3; i += 3) {
        /* read 3 bytes x 8 bits = 24 bits */
        if (false) {
#ifdef __GNUC__
        } else if (i) {
            __builtin_memcpy(&val, in + i - 1, sizeof(val));
            val = cbor_ntohl(val);
#endif
        } else {
            val = (in[i] << 16) | (in[i + 1] << 8) | in[i + 2];
        }

        /* write 4 chars x 6 bits = 24 bits */
        *out++ = alphabet[(val >> 18) & 0x3f];
        *out++ = alphabet[(val >> 12) & 0x3f];
        *out++ = alphabet[(val >> 6) & 0x3f];
        *out++ = alphabet[val & 0x3f];
    }

    /* maybe 1 or 2 bytes left */
    if (n - i) {
        /* we can read in[i + 1] even if it's past the end of the string because
         * we know (by construction) that it's a NUL byte */
#ifdef __GNUC__
        uint16_t val16;
        __builtin_memcpy(&val16, in + i, sizeof(val16));
        val = cbor_ntohs(val16);
#else
        val = (in[i] << 8) | in[i + 1];
#endif
        val <<= 8;

        /* the 65th character in the alphabet is our filler: either '=' or '\0' */
        out[4] = '\0';
        out[3] = alphabet[64];
        if (n - i == 2) {
            /* write the third char in 3 chars x 6 bits = 18 bits */
            out[2] = alphabet[(val >> 6) & 0x3f];
        } else {
            out[2] = alphabet[64];  /* filler */
        }
        out[1] = alphabet[(val >> 12) & 0x3f];
        out[0] = alphabet[(val >> 18) & 0x3f];
    } else {
        out[0] = '\0';
    }

    return CborNoError;
}

static CborError dump_bytestring_base64(char **result, CborValue *it)
{
    static const char alphabet[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
                                   "ghijklmn" "opqrstuv" "wxyz0123" "456789+/" "=";
    return generic_dump_base64(result, it, alphabet);
}

static CborError dump_bytestring_base64url(char **result, CborValue *it)
{
    static const char alphabet[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
                                   "ghijklmn" "opqrstuv" "wxyz0123" "456789-_";
    return generic_dump_base64(result, it, alphabet);
}

static CborError add_value_metadata(FILE *out, CborType type, const ConversionStatus *status)
{
    int flags = status->flags;
    if (flags & TypeWasTagged) {
        /* extract the tagged type, which may be JSON native */
        type = flags & FinalTypeMask;
        flags &= ~(FinalTypeMask | TypeWasTagged);

        if (fprintf(out, "\"tag\":\"%" PRIu64 "\"%s", status->lastTag,
                    flags & ~TypeWasTagged ? "," : "") < 0)
            return CborErrorIO;
    }

    if (!flags)
        return CborNoError;

    /* print at least the type */
    if (fprintf(out, "\"t\":%d", type) < 0)
        return CborErrorIO;

    if (flags & NumberWasNaN)
        if (fprintf(out, ",\"v\":\"nan\"") < 0)
            return CborErrorIO;
    if (flags & NumberWasInfinite)
        if (fprintf(out, ",\"v\":\"%sinf\"", flags & NumberWasNegative ? "-" : "") < 0)
            return CborErrorIO;
    if (flags & NumberPrecisionWasLost)
        if (fprintf(out, ",\"v\":\"%c%" PRIx64 "\"", flags & NumberWasNegative ? '-' : '+',
                    status->originalNumber) < 0)
            return CborErrorIO;
    if (type == CborSimpleType)
        if (fprintf(out, ",\"v\":%d", (int)status->originalNumber) < 0)
            return CborErrorIO;
    return CborNoError;
}

static CborError find_tagged_type(CborValue *it, CborTag *tag, CborType *type)
{
    CborError err = CborNoError;
    *type = cbor_value_get_type(it);
    while (*type == CborTagType) {
        cbor_value_get_tag(it, tag);    /* can't fail */
        err = cbor_value_advance_fixed(it);
        if (err)
            return err;

        *type = cbor_value_get_type(it);
    }
    return err;
}

static CborError tagged_value_to_json(FILE *out, CborValue *it, int flags, ConversionStatus *status)
{
    CborTag tag;
    CborError err;

    if (flags & CborConvertTagsToObjects) {
        cbor_value_get_tag(it, &tag);       /* can't fail */
        err = cbor_value_advance_fixed(it);
        if (err)
            return err;

        if (fprintf(out, "{\"tag%" PRIu64 "\":", tag) < 0)
            return CborErrorIO;

        CborType type = cbor_value_get_type(it);
        err = value_to_json(out, it, flags, type, status);
        if (err)
            return err;
        if (flags & CborConvertAddMetadata && status->flags) {
            if (fprintf(out, ",\"tag%" PRIu64 "$cbor\":{", tag) < 0 ||
                    add_value_metadata(out, type, status) != CborNoError ||
                    fputc('}', out) < 0)
                return CborErrorIO;
        }
        if (fputc('}', out) < 0)
            return CborErrorIO;
        status->flags = TypeWasNotNative | CborTagType;
        return CborNoError;
    }

    CborType type;
    err = find_tagged_type(it, &status->lastTag, &type);
    if (err)
        return err;
    tag = status->lastTag;

    /* special handling of byte strings? */
    if (type == CborByteStringType && (flags & CborConvertByteStringsToBase64Url) == 0 &&
            (tag == CborNegativeBignumTag || tag == CborExpectedBase16Tag || tag == CborExpectedBase64Tag)) {
        char *str;
        char *pre = "";

        if (tag == CborNegativeBignumTag) {
            pre = "~";
            err = dump_bytestring_base64url(&str, it);
        } else if (tag == CborExpectedBase64Tag) {
            err = dump_bytestring_base64(&str, it);
        } else { /* tag == CborExpectedBase16Tag */
            err = dump_bytestring_base16(&str, it);
        }
        if (err)
            return err;
        err = fprintf(out, "\"%s%s\"", pre, str) < 0 ? CborErrorIO : CborNoError;
        free(str);
        status->flags = TypeWasNotNative | TypeWasTagged | CborByteStringType;
        return err;
    }

    /* no special handling */
    err = value_to_json(out, it, flags, type, status);
    status->flags |= TypeWasTagged | type;
    return err;
}

static CborError stringify_map_key(char **key, CborValue *it, int flags, CborType type)
{
    (void)flags;    /* unused */
    (void)type;     /* unused */
#ifdef WITHOUT_OPEN_MEMSTREAM
    (void)key;      /* unused */
    (void)it;       /* unused */
    return CborErrorJsonNotImplemented;
#else
    size_t size;

    FILE *memstream = open_memstream(key, &size);
    if (memstream == NULL)
        return CborErrorOutOfMemory;        /* could also be EMFILE, but it's unlikely */
    CborError err = cbor_value_to_pretty_advance(memstream, it);

    if (unlikely(fclose(memstream) < 0 || *key == NULL))
        return CborErrorInternalError;
    return err;
#endif
}

static CborError array_to_json(FILE *out, CborValue *it, int flags, ConversionStatus *status)
{
    const char *comma = "";
    while (!cbor_value_at_end(it)) {
        if (fprintf(out, "%s", comma) < 0)
            return CborErrorIO;
        comma = ",";

        CborError err = value_to_json(out, it, flags, cbor_value_get_type(it), status);
        if (err)
            return err;
    }
    return CborNoError;
}

static CborError map_to_json(FILE *out, CborValue *it, int flags, ConversionStatus *status)
{
    const char *comma = "";
    CborError err;
    while (!cbor_value_at_end(it)) {
        char *key;
        if (fprintf(out, "%s", comma) < 0)
            return CborErrorIO;
        comma = ",";

        CborType keyType = cbor_value_get_type(it);
        if (likely(keyType == CborTextStringType)) {
            size_t n = 0;
            err = cbor_value_dup_text_string(it, &key, &n, it);
        } else if (flags & CborConvertStringifyMapKeys) {
            err = stringify_map_key(&key, it, flags, keyType);
        } else {
            return CborErrorJsonObjectKeyNotString;
        }
        if (err)
            return err;

        /* first, print the key */
        if (fprintf(out, "\"%s\":", key) < 0)
            return CborErrorIO;

        /* then, print the value */
        CborType valueType = cbor_value_get_type(it);
        err = value_to_json(out, it, flags, valueType, status);

        /* finally, print any metadata we may have */
        if (flags & CborConvertAddMetadata) {
            if (!err && keyType != CborTextStringType) {
                if (fprintf(out, ",\"%s$keycbordump\":true", key) < 0)
                    err = CborErrorIO;
            }
            if (!err && status->flags) {
                if (fprintf(out, ",\"%s$cbor\":{", key) < 0 ||
                        add_value_metadata(out, valueType, status) != CborNoError ||
                        fputc('}', out) < 0)
                    err = CborErrorIO;
            }
        }

        free(key);
        if (err)
            return err;
    }
    return CborNoError;
}

static CborError value_to_json(FILE *out, CborValue *it, int flags, CborType type, ConversionStatus *status)
{
    CborError err;
    status->flags = 0;

    switch (type) {
    case CborArrayType:
    case CborMapType: {
        /* recursive type */
        CborValue recursed;
        err = cbor_value_enter_container(it, &recursed);
        if (err) {
            it->ptr = recursed.ptr;
            return err;       /* parse error */
        }
        if (fputc(type == CborArrayType ? '[' : '{', out) < 0)
            return CborErrorIO;

        err = (type == CborArrayType) ?
                  array_to_json(out, &recursed, flags, status) :
                  map_to_json(out, &recursed, flags, status);
        if (err) {
            it->ptr = recursed.ptr;
            return err;       /* parse error */
        }

        if (fputc(type == CborArrayType ? ']' : '}', out) < 0)
            return CborErrorIO;
        err = cbor_value_leave_container(it, &recursed);
        if (err)
            return err;       /* parse error */

        status->flags = 0;    /* reset, there are never conversion errors for us */
        return CborNoError;
    }

    case CborIntegerType: {
        double num;     /* JS numbers are IEEE double precision */
        uint64_t val;
        cbor_value_get_raw_integer(it, &val);    /* can't fail */
        num = (double)val;

        if (cbor_value_is_negative_integer(it)) {
            num = -num - 1;                     /* convert to negative */
            if ((uint64_t)(-num - 1) != val) {
                status->flags = NumberPrecisionWasLost | NumberWasNegative;
                status->originalNumber = val;
            }
        } else {
            if ((uint64_t)num != val) {
                status->flags = NumberPrecisionWasLost;
                status->originalNumber = val;
            }
        }
        if (fprintf(out, "%.0f", num) < 0)  /* this number has no fraction, so no decimal points please */
            return CborErrorIO;
        break;
    }

    case CborByteStringType:
    case CborTextStringType: {
        char *str;
        if (type == CborByteStringType) {
            err = dump_bytestring_base64url(&str, it);
            status->flags = TypeWasNotNative;
        } else {
            size_t n = 0;
            err = cbor_value_dup_text_string(it, &str, &n, it);
        }
        if (err)
            return err;
        err = (fprintf(out, "\"%s\"", str) < 0) ? CborErrorIO : CborNoError;
        free(str);
        return err;
    }

    case CborTagType:
        return tagged_value_to_json(out, it, flags, status);

    case CborSimpleType: {
        uint8_t simple_type;
        cbor_value_get_simple_type(it, &simple_type);  /* can't fail */
        status->flags = TypeWasNotNative;
        status->originalNumber = simple_type;
        if (fprintf(out, "\"simple(%" PRIu8 ")\"", simple_type) < 0)
            return CborErrorIO;
        break;
    }

    case CborNullType:
        if (fprintf(out, "null") < 0)
            return CborErrorIO;
        break;

    case CborUndefinedType:
        status->flags = TypeWasNotNative;
        if (fprintf(out, "\"undefined\"") < 0)
            return CborErrorIO;
        break;

    case CborBooleanType: {
        bool val;
        cbor_value_get_boolean(it, &val);       /* can't fail */
        if (fprintf(out, val ? "true" : "false") < 0)
            return CborErrorIO;
        break;
    }

    case CborDoubleType: {
        double val;
        if (false) {
            float f;
    case CborFloatType:
            status->flags = TypeWasNotNative;
            cbor_value_get_float(it, &f);
            val = f;
        } else if (false) {
            uint16_t f16;
    case CborHalfFloatType:
            status->flags = TypeWasNotNative;
            cbor_value_get_half_float(it, &f16);
            val = decode_half(f16);
        } else {
            cbor_value_get_double(it, &val);
        }

        int r = fpclassify(val);
        if (r == FP_NAN || r == FP_INFINITE) {
            if (fprintf(out, "null") < 0)
                return CborErrorIO;
            status->flags |= r == FP_NAN ? NumberWasNaN :
                                           NumberWasInfinite | (val < 0 ? NumberWasNegative : 0);
        } else {
            uint64_t ival = (uint64_t)fabs(val);
            if ((double)ival == fabs(val)) {
                /* print as integer so we get the full precision */
                r = fprintf(out, "%s%" PRIu64, val < 0 ? "-" : "", ival);
                status->flags |= TypeWasNotNative;   /* mark this integer number as a double */
            } else {
                /* this number is definitely not a 64-bit integer */
                r = fprintf(out, "%." DBL_DECIMAL_DIG_STR "g", val);
            }
            if (r < 0)
                return CborErrorIO;
        }
        break;
    }

    case CborInvalidType:
        return CborErrorUnknownType;
    }

    return cbor_value_advance_fixed(it);
}

/**
 * \enum CborToJsonFlags
 * The CborToJsonFlags enum contains flags that control the conversion of CBOR to JSON.
 *
 * \value CborConvertAddMetadata        Adds metadata to facilitate restoration of the original CBOR data.
 * \value CborConvertTagsToObjects      Converts CBOR tags to JSON objects
 * \value CborConvertIgnoreTags         (default) Ignore CBOR tags, except for byte strings
 * \value CborConvertObeyByteStringTags (default) Honor formatting of CBOR byte strings if so tagged
 * \value CborConvertByteStringsToBase64Url Force the conversion of all CBOR byte strings to Base64url encoding, despite any tags
 * \value CborConvertRequireMapStringKeys (default) Require CBOR map keys to be strings, failing the conversion if they are not
 * \value CborConvertStringifyMapKeys   Convert non-string keys in CBOR maps to a string form
 * \value CborConvertDefaultFlags       Default conversion flags.
 */

/**
 * \fn CborError cbor_value_to_json(FILE *out, const CborValue *value, int flags)
 *
 * Converts the current CBOR type pointed by \a value to JSON and writes that
 * to the \a out stream. If an error occurs, this function returns an error
 * code similar to CborParsing. The \a flags parameter indicates one of the
 * flags from CborToJsonFlags that control the conversion.
 *
 * \sa cbor_value_to_json_advance(), cbor_value_to_pretty()
 */

/**
 * Converts the current CBOR type pointed by \a value to JSON and writes that
 * to the \a out stream. If an error occurs, this function returns an error
 * code similar to CborParsing. The \a flags parameter indicates one of the
 * flags from CborToJsonFlags that control the conversion.
 *
 * If no error ocurred, this function advances \a value to the next element.
 *
 * \sa cbor_value_to_json(), cbor_value_to_pretty_advance()
 */
CborError cbor_value_to_json_advance(FILE *out, CborValue *value, int flags)
{
    ConversionStatus status;
    return value_to_json(out, value, flags, cbor_value_get_type(value), &status);
}

/** @} */
