/*
 * DO NOT EDIT THIS FILE. Generated by checkmk.
 * Edit the original source file "test_table_resize.template" instead.
 * Run `make internals` from the base of the project to regenerate this file.
 */

#include <check.h>

#line 1 "test_table_resize.template"
/**
 * This file is part of the Detox package.
 *
 * Copyright (c) Doug Harple <detox.dharple@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <unistd.h>

#include "parse_table.h"
#include "table.h"

struct test_definition {
    int pass;
    int size;
    int multiple;
};

static struct test_definition tests[5] = {
    { .pass = 1, .size = 0 },
    { .pass = 2, .size = 10000 },
    { .pass = 3, .size = 1000000 },
    { .pass = 4, .size = 0, .multiple = 16 },
    { .pass = -1 }
};

struct test_value {
    int value;
    char *expected;
};

static struct test_value values[9] = {
    { .value = 0x0020, .expected = "space" },
    { .value = 0x00A3, .expected = "_pound_" },
    { .value = 0x014B, .expected = "ng" },
    { .value = 0x0BAD, .expected = NULL },
    { .value = 0x4000, .expected = NULL },
    { .value = 0xC0DE, .expected = "code" },
    { .value = 0xCAFE, .expected = "cafe" },
    { .value = 0xFACE, .expected = "face" },
    { .value = 0 }
};

static char *table_filename = "fixtures/test_table_resize.tbl";

#define HEADER_LEN 256
#define MESSAGE_LEN 1024

START_TEST(test_table_resize)
{
#line 58
    table_t *table;
    table_t *new_table;
    char *check;
    char *header;
    char *message;
    int i, j;
    int size;
    int use_hash;

    header = malloc(HEADER_LEN);
    message = malloc(MESSAGE_LEN);

    for (use_hash = 0; use_hash <= 1; use_hash++) {
        table = parse_table(table_filename);

        for (i = 0; tests[i].pass != -1; i++) {
            snprintf(header, HEADER_LEN, "pass = %d, use_hash = %d", tests[i].pass, use_hash);
#ifdef DEBUG
            printf("%s\n", header);
#endif

            if (tests[i].size > 0) {
#ifdef DEBUG
                printf("resizing table to size %d\n", tests[i].size);
#endif
                new_table = table_resize(table, tests[i].size, use_hash);
                table_free(table);
                table = new_table;
                new_table = NULL;
            } else if (tests[i].multiple > 0) {
                size = ((int) ceil(table->used / tests[i].multiple) + 1) * tests[i].multiple;
#ifdef DEBUG
                printf("resizing table to size %d (as a multiple of %d)\n", size, tests[i].multiple);
#endif
                new_table = table_resize(table, size, use_hash);
                table_free(table);
                table = new_table;
                new_table = NULL;
            }

#ifdef DEBUG
            printf("table length: %d\ntable used: %d\n", table->length, table->used);
#endif

            for (j = 0; values[j].value != 0; j++) {
                check = table_get(table, values[j].value);
#ifdef DEBUG
                printf("\t0x%04x -> \"%s\"\n", values[j].value, check);
#endif
                snprintf(
                    message,
                    MESSAGE_LEN,
                    "%s, value = 0x%04X, expected = %s, output = %s",
                    header,
                    values[j].value,
                    values[j].expected,
                    check
                );

                if (values[j].expected != NULL) {
                    ck_assert_msg(check != NULL, message);
                    ck_assert_msg(strcmp(check, values[j].expected) == 0, message);
                } else {
                    ck_assert_msg(check == NULL, message);
                }
            }
        }

        table_free(table);
    }
}
END_TEST

int main(void)
{
    Suite *s1 = suite_create("Core");
    TCase *tc1_1 = tcase_create("Core");
    SRunner *sr = srunner_create(s1);
    int nf;

    suite_add_tcase(s1, tc1_1);
    tcase_add_test(tc1_1, test_table_resize);

    srunner_run_all(sr, CK_ENV);
    nf = srunner_ntests_failed(sr);
    srunner_free(sr);

    return nf == 0 ? 0 : 1;
}
