/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <ctype.h>
#include <stdlib.h>

#include "apr_json.h"

#define APR_JSON_OBJECT_INSERT_TAIL(o, e) do {                              \
        apr_json_kv_t *ap__b = (e);                                        \
        APR_RING_INSERT_TAIL(&(o)->list, ap__b, apr_json_kv_t, link);      \
        APR_RING_CHECK_CONSISTENCY(&(o)->list, apr_json_kv_t, link);                             \
    } while (0)

#define APR_JSON_ARRAY_INSERT_TAIL(o, e) do {                              \
        apr_json_value_t *ap__b = (e);                                        \
        APR_RING_INSERT_TAIL(&(o)->list, ap__b, apr_json_value_t, link);      \
        APR_RING_CHECK_CONSISTENCY(&(o)->list, apr_json_value_t, link);                             \
    } while (0)

APR_DECLARE(apr_json_value_t *) apr_json_value_create(apr_pool_t *pool)
{
    return apr_pcalloc(pool, sizeof(apr_json_value_t));
}

APR_DECLARE(apr_json_value_t *) apr_json_object_create(apr_pool_t *pool)
{
    apr_json_object_t *object;

    apr_json_value_t *json = apr_json_value_create(pool);

    json->type = APR_JSON_OBJECT;
    json->value.object = object = apr_pcalloc(pool, sizeof(apr_json_object_t));
    APR_RING_INIT(&object->list, apr_json_kv_t, link);
    object->hash = apr_hash_make(pool);

    return json;
}

APR_DECLARE(apr_json_value_t *) apr_json_string_create(apr_pool_t *pool,
                                                       const char *val,
                                                       apr_ssize_t len)
{
    apr_json_value_t *json = apr_json_value_create(pool);

    if (json) {
        if (val) {
            json->type = APR_JSON_STRING;
            json->value.string.p = val;
            json->value.string.len = len;
        } else {
            json->type = APR_JSON_NULL;
        }
    }

    return json;
}

APR_DECLARE(apr_json_value_t *) apr_json_array_create(apr_pool_t *pool, int nelts)
{
    apr_json_value_t *json = apr_json_value_create(pool);

    if (json) {
        json->type = APR_JSON_ARRAY;
        json->value.array = apr_pcalloc(pool, sizeof(apr_json_array_t));
        APR_RING_INIT(&json->value.array->list, apr_json_value_t, link);
        json->value.array->array = apr_array_make(pool, nelts,
                sizeof(apr_json_value_t *));
    }

    return json;
}

APR_DECLARE(apr_json_value_t *) apr_json_long_create(apr_pool_t *pool, apr_int64_t lnumber)
{
    apr_json_value_t *json = apr_json_value_create(pool);

    if (json) {
        json->type = APR_JSON_LONG;
        json->value.lnumber = lnumber;
    }

    return json;
}

APR_DECLARE(apr_json_value_t *) apr_json_double_create(apr_pool_t *pool, double dnumber)
{
    apr_json_value_t *json = apr_json_value_create(pool);

    if (json) {
        json->type = APR_JSON_DOUBLE;
        json->value.dnumber = dnumber;
    }

    return json;
}

APR_DECLARE(apr_json_value_t *) apr_json_boolean_create(apr_pool_t *pool, int boolean)
{
    apr_json_value_t *json = apr_json_value_create(pool);

    if (json) {
        json->type = APR_JSON_BOOLEAN;
        json->value.boolean = boolean;
    }

    return json;
}

APR_DECLARE(apr_json_value_t *) apr_json_null_create(apr_pool_t *pool)
{
    apr_json_value_t *json = apr_json_value_create(pool);

    if (json) {
        json->type = APR_JSON_NULL;
    }

    return json;
}

APR_DECLARE(apr_status_t) apr_json_object_set(apr_json_value_t *object,
        const char *key, apr_ssize_t klen, apr_json_value_t *val,
        apr_pool_t *pool)
{
    apr_json_kv_t *kv;
    apr_hash_t *hash;

    if (object->type != APR_JSON_OBJECT) {
        return APR_EINVAL;
    }

    if (klen == APR_JSON_VALUE_STRING) {
        klen = strlen(key);
    }

    hash = object->value.object->hash;

    kv = apr_hash_get(hash, key, klen);

    if (!val) {
        if (kv) {
            apr_hash_set(hash, key, klen, NULL);
            APR_RING_REMOVE((kv), link);
        }
        return APR_SUCCESS;
    }

    if (!kv) {
        kv = apr_palloc(pool, sizeof(apr_json_kv_t));
        APR_RING_ELEM_INIT(kv, link);
        APR_JSON_OBJECT_INSERT_TAIL(object->value.object, kv);
        apr_hash_set(hash, key, klen,
                kv);
    }

    kv->k = apr_json_string_create(pool, key, klen);
    kv->v = val;

    return APR_SUCCESS;
}

APR_DECLARE(apr_status_t) apr_json_object_set_ex(apr_json_value_t *object,
                                                 apr_json_value_t *key,
                                                 apr_json_value_t *val,
                                                 apr_pool_t *pool)
{
    apr_json_kv_t *kv;
    apr_hash_t *hash;

    if (object->type != APR_JSON_OBJECT
            || key->type != APR_JSON_STRING) {
        return APR_EINVAL;
    }

    hash = object->value.object->hash;

    kv = apr_hash_get(hash, key->value.string.p, key->value.string.len);

    if (!val) {
        if (kv) {
            apr_hash_set(hash, key->value.string.p, key->value.string.len,
                    NULL);
            APR_RING_REMOVE((kv), link);
        }
        return APR_SUCCESS;
    }

    if (!kv) {
        kv = apr_palloc(pool, sizeof(apr_json_kv_t));
        APR_RING_ELEM_INIT(kv, link);
        APR_JSON_OBJECT_INSERT_TAIL(object->value.object, kv);
        apr_hash_set(hash, key->value.string.p, key->value.string.len,
                kv);
    }

    kv->k = key;
    kv->v = val;

    return APR_SUCCESS;
}

APR_DECLARE(apr_json_kv_t *) apr_json_object_get(apr_json_value_t *object,
                                                 const char *key,
                                                 apr_ssize_t klen)
{
    if (object->type != APR_JSON_OBJECT) {
        return NULL;
    }

    return apr_hash_get(object->value.object->hash, key, klen);
}

APR_DECLARE(apr_json_kv_t *) apr_json_object_first(apr_json_value_t *obj)
{
    apr_json_kv_t *kv;

    if (obj->type != APR_JSON_OBJECT) {
        return NULL;
    }

    kv = APR_RING_FIRST(&(obj->value.object)->list);

    if (kv != APR_RING_SENTINEL(&(obj->value.object)->list, apr_json_kv_t, link)) {
        return kv;
    }
    else {
        return NULL;
    }
}

APR_DECLARE(apr_json_kv_t *) apr_json_object_next(apr_json_value_t *obj,
                                                  apr_json_kv_t *kv)
{
    apr_json_kv_t *next;

    if (obj->type != APR_JSON_OBJECT) {
        return NULL;
    }

    next = APR_RING_NEXT((kv), link);

    if (next != APR_RING_SENTINEL(&(obj->value.object)->list, apr_json_kv_t, link)) {
        return next;
    }
    else {
        return NULL;
    }
}

APR_DECLARE(apr_status_t) apr_json_array_add(apr_json_value_t *arr,
                                             apr_json_value_t *val)
{
    apr_array_header_t *array;

    if (arr->type != APR_JSON_ARRAY) {
        return APR_EINVAL;
    }

    APR_RING_ELEM_INIT(val, link);
    APR_JSON_ARRAY_INSERT_TAIL(arr->value.array, val);

    array = arr->value.array->array;
    if (array) {
        *((apr_json_value_t **) (apr_array_push(array))) = val;
    }

    return APR_SUCCESS;
}

APR_DECLARE(apr_json_value_t *) apr_json_array_get(apr_json_value_t *arr,
                                                   int index)
{
    if (arr->type != APR_JSON_ARRAY) {
        return NULL;
    }

    return APR_ARRAY_IDX(arr->value.array->array, index, apr_json_value_t *);
}

APR_DECLARE(apr_json_value_t *) apr_json_array_first(const apr_json_value_t *arr)
{
    apr_json_value_t *val;

    if (arr->type != APR_JSON_ARRAY) {
        return NULL;
    }

    val = APR_RING_FIRST(&(arr->value.array)->list);

    if (val
            != APR_RING_SENTINEL(&(arr->value.object)->list, apr_json_value_t,
                    link)) {
        return val;
    } else {
        return NULL;
    }
}

APR_DECLARE(apr_json_value_t *) apr_json_array_next(const apr_json_value_t *arr,
                                                    const apr_json_value_t *val)
{
    apr_json_value_t *next;

    if (arr->type != APR_JSON_ARRAY) {
        return NULL;
    }

    next = APR_RING_NEXT((val), link);

    if (next
            != APR_RING_SENTINEL(&(arr->value.array)->list, apr_json_value_t,
                    link)) {
        return next;
    } else {
        return NULL;
    }
}

APR_DECLARE(apr_json_value_t *) apr_json_overlay(apr_pool_t *p,
                                                 apr_json_value_t *overlay,
                                                 apr_json_value_t *base,
                                                 int flags)
{
    apr_json_value_t *res;
    apr_json_kv_t *kv;
    int oc, bc;

    if (!base || base->type != APR_JSON_OBJECT) {
        return overlay;
    }
    if (!overlay) {
        return base;
    }
    if (overlay->type != APR_JSON_OBJECT) {
        return overlay;
    }

    oc = apr_hash_count(overlay->value.object->hash);
    if (!oc) {
        return base;
    }
    bc = apr_hash_count(base->value.object->hash);
    if (!bc) {
        return overlay;
    }

    res = apr_json_object_create(p);

    for (kv = APR_RING_FIRST(&(base->value.object)->list);
         kv != APR_RING_SENTINEL(&(base->value.object)->list, apr_json_kv_t, link);
         kv = APR_RING_NEXT((kv), link)) {

        if (!apr_hash_get(overlay->value.object->hash, kv->k->value.string.p,
                kv->k->value.string.len)) {

            apr_json_object_set_ex(res, kv->k, kv->v, p);

        }
        else if (APR_JSON_FLAGS_STRICT & flags) {
            return NULL;
        }

    }

    for (kv = APR_RING_FIRST(&(overlay->value.object)->list);
         kv != APR_RING_SENTINEL(&(overlay->value.object)->list, apr_json_kv_t, link);
         kv = APR_RING_NEXT((kv), link)) {

        apr_json_object_set_ex(res, kv->k, kv->v, p);

    }

    return res;
}
