/*
 * 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 "crypto/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;
}
