/*
 * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
 * Copyright (c) 2019, Oracle and/or its affiliates.  All rights reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <stdio.h>
#include <string.h>
#include <limits.h>

#include <openssl/crypto.h>
#include <internal/nelem.h>

#include "internal/sparse_array.h"
#include "testutil.h"

/* The macros below generate unused functions which error out one of the clang
 * builds.  We disable this check here.
 */
#ifdef __clang__
#pragma clang diagnostic ignored "-Wunused-function"
#endif

DEFINE_SPARSE_ARRAY_OF(char);

static int test_sparse_array(void)
{
    static const struct {
        ossl_uintmax_t n;
        char *v;
    } cases[] = {
        { 22, "a" }, { 0, "z" }, { 1, "b" }, { 290, "c" },
        { INT_MAX, "m" }, { 6666666, "d" }, { (ossl_uintmax_t)-1, "H" },
        { 99, "e" }
    };
    SPARSE_ARRAY_OF(char) *sa;
    size_t i, j;
    int res = 0;

    if (!TEST_ptr(sa = ossl_sa_char_new())
            || !TEST_ptr_null(ossl_sa_char_get(sa, 3))
            || !TEST_ptr_null(ossl_sa_char_get(sa, 0))
            || !TEST_ptr_null(ossl_sa_char_get(sa, UINT_MAX)))
        goto err;

    for (i = 0; i < OSSL_NELEM(cases); i++) {
        if (!TEST_true(ossl_sa_char_set(sa, cases[i].n, cases[i].v))) {
            TEST_note("iteration %zu", i + 1);
            goto err;
        }
        for (j = 0; j <= i; j++)
            if (!TEST_str_eq(ossl_sa_char_get(sa, cases[j].n), cases[j].v)) {
                TEST_note("iteration %zu / %zu", i + 1, j + 1);
                goto err;
            }
    }

    res = 1;
err:
    ossl_sa_char_free(sa);
    return res;
}

static int test_sparse_array_num(void)
{
    static const struct {
        size_t num;
        ossl_uintmax_t n;
        char *v;
    } cases[] = {
        { 1, 22, "a" }, { 2, 1021, "b" }, { 3, 3, "c" }, { 2, 22, NULL },
        { 2, 3, "d" }, { 3, 22, "e" }, { 3, 666, NULL }, { 4, 666, "f" },
        { 3, 3, NULL }, { 2, 22, NULL }, { 1, 666, NULL }, { 2, 64000, "g" },
        { 1, 1021, NULL }, { 0, 64000, NULL }, { 1, 23, "h" }, { 0, 23, NULL }
    };
    SPARSE_ARRAY_OF(char) *sa = NULL;
    size_t i;
    int res = 0;

    if (!TEST_size_t_eq(ossl_sa_char_num(NULL), 0)
            || !TEST_ptr(sa = ossl_sa_char_new())
            || !TEST_size_t_eq(ossl_sa_char_num(sa), 0))
        goto err;
    for (i = 0; i < OSSL_NELEM(cases); i++)
        if (!TEST_true(ossl_sa_char_set(sa, cases[i].n, cases[i].v))
                || !TEST_size_t_eq(ossl_sa_char_num(sa), cases[i].num))
            goto err;
    res = 1;
err:
    ossl_sa_char_free(sa);
    return res;
}

struct index_cases_st {
    ossl_uintmax_t n;
    char *v;
    int del;
};

struct doall_st {
    SPARSE_ARRAY_OF(char) *sa;
    size_t num_cases;
    const struct index_cases_st *cases;
    int res;
    int all;
};

static void leaf_check_all(ossl_uintmax_t n, char *value, void *arg)
{
    struct doall_st *doall_data = (struct doall_st *)arg;
    const struct index_cases_st *cases = doall_data->cases;
    size_t i;

    doall_data->res = 0;
    for (i = 0; i < doall_data->num_cases; i++)
        if ((doall_data->all || !cases[i].del)
            && n == cases[i].n && strcmp(value, cases[i].v) == 0) {
            doall_data->res = 1;
            return;
        }
    TEST_error("Index %ju with value %s not found", n, value);
}

static void leaf_delete(ossl_uintmax_t n, char *value, void *arg)
{
    struct doall_st *doall_data = (struct doall_st *)arg;
    const struct index_cases_st *cases = doall_data->cases;
    size_t i;

    doall_data->res = 0;
    for (i = 0; i < doall_data->num_cases; i++)
        if (n == cases[i].n && strcmp(value, cases[i].v) == 0) {
            doall_data->res = 1;
            ossl_sa_char_set(doall_data->sa, n, NULL);
            return;
        }
    TEST_error("Index %ju with value %s not found", n, value);
}

static int test_sparse_array_doall(void)
{
    static const struct index_cases_st cases[] = {
        { 22, "A", 1 }, { 1021, "b", 0 }, { 3, "c", 0 }, { INT_MAX, "d", 1 },
        { (ossl_uintmax_t)-1, "H", 0 }, { (ossl_uintmax_t)-2, "i", 1 },
        { 666666666, "s", 1 }, { 1234567890, "t", 0 },
    };
    struct doall_st doall_data;
    size_t i;
    SPARSE_ARRAY_OF(char) *sa = NULL;
    int res = 0;

    if (!TEST_ptr(sa = ossl_sa_char_new()))
        goto err;
    doall_data.num_cases = OSSL_NELEM(cases);
    doall_data.cases = cases;
    doall_data.all = 1;
    doall_data.sa = NULL;
    for (i = 0; i <  OSSL_NELEM(cases); i++)
        if (!TEST_true(ossl_sa_char_set(sa, cases[i].n, cases[i].v))) {
            TEST_note("failed at iteration %zu", i + 1);
            goto err;
    }

    ossl_sa_char_doall_arg(sa, &leaf_check_all, &doall_data);
    if (doall_data.res == 0) {
        TEST_info("while checking all elements");
        goto err;
    }
    doall_data.all = 0;
    doall_data.sa = sa;
    ossl_sa_char_doall_arg(sa, &leaf_delete, &doall_data);
    if (doall_data.res == 0) {
        TEST_info("while deleting selected elements");
        goto err;
    }
    ossl_sa_char_doall_arg(sa, &leaf_check_all, &doall_data);
    if (doall_data.res == 0) {
        TEST_info("while checking for deleted elements");
        goto err;
    }
    res = 1;

err:
    ossl_sa_char_free(sa);
    return res;
}

int setup_tests(void)
{
    ADD_TEST(test_sparse_array);
    ADD_TEST(test_sparse_array_num);
    ADD_TEST(test_sparse_array_doall);
    return 1;
}
