/*
 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
 *
 * This software is dual-licensed to you under the MIT License (MIT) and
 * the Universal Permissive License (UPL). See the LICENSE file in the root
 * directory for license terms. You may choose either license, or both.
 */


#ifndef JSON_HELPER_H
#define    JSON_HELPER_H

#include <string.h>
#include "external/json_parser/jsmn.h"
#include "iotcs.h"

/**
 * @brief Common private header
 */

#ifdef    __cplusplus
extern "C" {
#endif

    // temperature_sensor DM contain 238 tokens, but it may be more
#ifndef IOTCS_JSON_TOKEN_NUM
#define IOTCS_JSON_TOKEN_NUM 512
#endif

    typedef struct {
        int count;
        int index;
        const char* json;
    } json_tokens_t;

    typedef struct {
        int next;
        json_tokens_t* tok;
    } json_object_iterator_t;

    typedef struct {
        int next;
        json_tokens_t* tok;
    } json_array_iterator_t;

    iotcs_result json_parse(const char *json, size_t json_len, json_tokens_t* out_tok);
    iotcs_result json_get_string_value_by_key(json_tokens_t* tok, const char* key, char** value, int* value_length);
    iotcs_result json_get_int_value_by_key(json_tokens_t* tok, const char* key, int64_t* value);
    iotcs_result json_get_float_value_by_key(json_tokens_t* tok, const char* key, float* value);
    iotcs_result json_get_bool_value_by_key(json_tokens_t* tok, const char* key, iotcs_bool* value);
    iotcs_result json_get_object_by_key(json_tokens_t* tok, const char* key, json_tokens_t* out_tok);
    iotcs_result json_get_array_by_key(json_tokens_t* tok, const char* key, json_tokens_t* out_tok);
#if defined IOTCS_STORAGE_SUPPORT
    iotcs_result json_get_storage_object_url_by_key(json_tokens_t* tok, const char** url);
#endif

    /* number of child objects for this token: prim - 0, field - 1, array - item num, object - fields num */
    int json_child_items_count(json_tokens_t* tok);
    /* length of item in bytes */
    int json_get_length(json_tokens_t* tok);
    iotcs_result json_get_string_and_move(json_tokens_t* tok, char** out_string, int* out_len);

    // iteration
    iotcs_result json_get_object_iterator(json_tokens_t* tok, json_object_iterator_t* iter);
    iotcs_bool json_object_iterator_has_next(json_object_iterator_t* iter);
    iotcs_result json_object_iterator_next(json_object_iterator_t* iter, json_tokens_t* next_tok);

    iotcs_result json_get_array_iterator(json_tokens_t* tok, json_array_iterator_t* iter);
    iotcs_bool json_array_iterator_has_next(json_array_iterator_t* iter);
    iotcs_result json_array_iterator_next(json_array_iterator_t* iter, json_tokens_t* next_tok);
    iotcs_result json_get_iotcs_value(json_tokens_t* tok, iotcs_typed_value *ptyped_value);

#ifdef    __cplusplus
}
#endif

#endif    /* JSON_HELPER_H */

