/* 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 "testutil.h"
#include "apr.h"
#include "apr_strings.h"
#include "apr_general.h"
#include "apr_pools.h"
#include "apr_tables.h"
#if APR_HAVE_STDIO_H
#include <stdio.h>
#endif
#if APR_HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if APR_HAVE_STRING_H
#include <string.h>
#endif

static apr_array_header_t *a1 = NULL;
static apr_table_t *t1 = NULL;

static void array_clear(abts_case *tc, void *data)
{
    a1 = apr_array_make(p, 2, sizeof(const char *));
    APR_ARRAY_PUSH(a1, const char *) = "foo";
    APR_ARRAY_PUSH(a1, const char *) = "bar";
    apr_array_clear(a1);
    ABTS_INT_EQUAL(tc, 0, a1->nelts);
}

static void table_make(abts_case *tc, void *data)
{
    t1 = apr_table_make(p, 5);
    ABTS_PTR_NOTNULL(tc, t1);
}

static void table_get(abts_case *tc, void *data)
{
    const char *val;

    apr_table_set(t1, "foo", "bar");
    val = apr_table_get(t1, "foo");
    ABTS_STR_EQUAL(tc, "bar", val);
}

static void table_getm(abts_case *tc, void *data)
{
    const char *orig, *val;
    apr_pool_t *subp;

    apr_pool_create(&subp, p);

    orig = "bar";
    apr_table_setn(t1, "foo", orig);
    val = apr_table_getm(subp, t1, "foo");
    ABTS_PTR_EQUAL(tc, orig, val);
    ABTS_STR_EQUAL(tc, "bar", val);
    apr_table_add(t1, "foo", "baz");
    val = apr_table_getm(subp, t1, "foo");
    ABTS_STR_EQUAL(tc, "bar,baz", val);

    apr_pool_destroy(subp);
}

static void table_set(abts_case *tc, void *data)
{
    const char *val;

    apr_table_set(t1, "setkey", "bar");
    apr_table_set(t1, "setkey", "2ndtry");
    val = apr_table_get(t1, "setkey");
    ABTS_STR_EQUAL(tc, "2ndtry", val);
}

static void table_getnotthere(abts_case *tc, void *data)
{
    const char *val;

    val = apr_table_get(t1, "keynotthere");
    ABTS_PTR_EQUAL(tc, NULL, (void *)val);
}

static void table_add(abts_case *tc, void *data)
{
    const char *val;

    apr_table_add(t1, "addkey", "bar");
    apr_table_add(t1, "addkey", "foo");
    val = apr_table_get(t1, "addkey");
    ABTS_STR_EQUAL(tc, "bar", val);

}

static void table_nelts(abts_case *tc, void *data)
{
    const char *val;
    apr_table_t *t = apr_table_make(p, 1);

    apr_table_set(t, "abc", "def");
    apr_table_set(t, "def", "abc");
    apr_table_set(t, "foo", "zzz");
    val = apr_table_get(t, "foo");
    ABTS_STR_EQUAL(tc, "zzz", val);
    val = apr_table_get(t, "abc");
    ABTS_STR_EQUAL(tc, "def", val);
    val = apr_table_get(t, "def");
    ABTS_STR_EQUAL(tc, "abc", val);
    ABTS_INT_EQUAL(tc, 3, apr_table_elts(t)->nelts);
}

static void table_clear(abts_case *tc, void *data)
{
    apr_table_clear(t1);
    ABTS_INT_EQUAL(tc, 0, apr_table_elts(t1)->nelts);
}

static void table_unset(abts_case *tc, void *data)
{
    const char *val;
    apr_table_t *t = apr_table_make(p, 1);

    apr_table_set(t, "a", "1");
    apr_table_set(t, "b", "2");
    apr_table_unset(t, "b");
    ABTS_INT_EQUAL(tc, 1, apr_table_elts(t)->nelts);
    val = apr_table_get(t, "a");
    ABTS_STR_EQUAL(tc, "1", val);
    val = apr_table_get(t, "b");
    ABTS_PTR_EQUAL(tc, (void *)NULL, (void *)val);
}

static void table_overlap(abts_case *tc, void *data)
{
    const char *val;
    apr_table_t *t1 = apr_table_make(p, 1);
    apr_table_t *t2 = apr_table_make(p, 1);

    apr_table_addn(t1, "a", "0");
    apr_table_addn(t1, "g", "7");
    apr_table_addn(t2, "a", "1");
    apr_table_addn(t2, "b", "2");
    apr_table_addn(t2, "c", "3");
    apr_table_addn(t2, "b", "2.0");
    apr_table_addn(t2, "d", "4");
    apr_table_addn(t2, "e", "5");
    apr_table_addn(t2, "b", "2.");
    apr_table_addn(t2, "f", "6");
    apr_table_overlap(t1, t2, APR_OVERLAP_TABLES_SET);

    ABTS_INT_EQUAL(tc, 7, apr_table_elts(t1)->nelts);
    val = apr_table_get(t1, "a");
    ABTS_STR_EQUAL(tc, "1", val);
    val = apr_table_get(t1, "b");
    ABTS_STR_EQUAL(tc, "2.", val);
    val = apr_table_get(t1, "c");
    ABTS_STR_EQUAL(tc, "3", val);
    val = apr_table_get(t1, "d");
    ABTS_STR_EQUAL(tc, "4", val);
    val = apr_table_get(t1, "e");
    ABTS_STR_EQUAL(tc, "5", val);
    val = apr_table_get(t1, "f");
    ABTS_STR_EQUAL(tc, "6", val);
    val = apr_table_get(t1, "g");
    ABTS_STR_EQUAL(tc, "7", val);
}

static void table_overlap2(abts_case *tc, void *data)
{
    apr_pool_t *subp;
    apr_table_t *t1, *t2;

    apr_pool_create(&subp, p);

    t1 = apr_table_make(subp, 1);
    t2 = apr_table_make(p, 1);
    apr_table_addn(t1, "t1", "one");
    apr_table_addn(t2, "t2", "two");

    apr_table_overlap(t1, t2, APR_OVERLAP_TABLES_SET);

    ABTS_INT_EQUAL(tc, 2, apr_table_elts(t1)->nelts);

    ABTS_STR_EQUAL(tc, "one", apr_table_get(t1, "t1"));
    ABTS_STR_EQUAL(tc, "two", apr_table_get(t1, "t2"));

}

static void table_overlap3(abts_case *tc, void *data)
{
    apr_pool_t *subp;
    apr_table_t *t1, *t2;

    apr_pool_create(&subp, p);

    t1 = apr_table_make(subp, 1);
    t2 = apr_table_make(p, 1);
    apr_table_addn(t1, "t1", "one");
    apr_table_addn(t1, "t1", "overlay");
    apr_table_addn(t2, "t2", "two");
    apr_table_addn(t2, "t2", "overlay");

    apr_table_overlap(t1, t2, APR_OVERLAP_TABLES_ADD);

    ABTS_INT_EQUAL(tc, 4, apr_table_elts(t1)->nelts);

    ABTS_STR_EQUAL(tc, "one", apr_table_get(t1, "t1"));
    ABTS_STR_EQUAL(tc, "two", apr_table_get(t1, "t2"));

}

abts_suite *testtable(abts_suite *suite)
{
    suite = ADD_SUITE(suite)

    abts_run_test(suite, array_clear, NULL);
    abts_run_test(suite, table_make, NULL);
    abts_run_test(suite, table_get, NULL);
    abts_run_test(suite, table_getm, NULL);
    abts_run_test(suite, table_set, NULL);
    abts_run_test(suite, table_getnotthere, NULL);
    abts_run_test(suite, table_add, NULL);
    abts_run_test(suite, table_nelts, NULL);
    abts_run_test(suite, table_clear, NULL);
    abts_run_test(suite, table_unset, NULL);
    abts_run_test(suite, table_overlap, NULL);
    abts_run_test(suite, table_overlap2, NULL);
    abts_run_test(suite, table_overlap3, NULL);

    return suite;
}

