/* $Id$ 
 * 
 * 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. 
 */ 

/*
 * test_hashing.c 
 * test hashing of various complex items and associated memory management 
 */
#include "apr_time.h" /* some apr must be included first */
#include "etch_binary_tdi.h"  /* must be included second */
#include "etch_binary_tdo.h"

#include <tchar.h>
#include <stdio.h>
#include <conio.h>

#include "cunit.h"
#include "basic.h"
#include "automated.h"

#include "etch_connection.h"
#include "etch_global.h"
#include "etch_id_name.h"
#include "etch_field.h"
#include "etch_type.h"
#include "etchlog.h"

int apr_setup(void);
int apr_teardown(void);
int this_setup();
int this_teardown();
apr_pool_t* g_apr_mempool;
const char* pooltag = "etchpool";
#define IS_DEBUG_CONSOLE FALSE


int init_suite(void)
{
    apr_setup();
    etch_runtime_init(TRUE);
    return this_setup();
}

int clean_suite(void)
{
    this_teardown();
    etch_runtime_cleanup(0,0); /* free memtable and cache etc */
    apr_teardown();
    return 0;
}


/*
 * apr_setup()
 * establish apache portable runtime environment
 */
int apr_setup(void)
{
    int result = apr_initialize();
    if (result == 0)
    {   result = etch_apr_init();
        g_apr_mempool = etch_apr_mempool;
    }
    if (g_apr_mempool)
        apr_pool_tag(g_apr_mempool, pooltag);
    else result = -1;
    return result;
}

/*
 * apr_teardown()
 * free apache portable runtime environment
 */
int apr_teardown(void)
{
    if (g_apr_mempool)
        apr_pool_destroy(g_apr_mempool);
    g_apr_mempool = NULL;
    apr_terminate();
    return 0;
}


/* - - - - - - - - - - - - - - - - - - - - - - 
 * local declarations 
 * - - - - - - - - - - - - - - - - - - - - - -
 */


/* - - - - - - - - - - - - - - - - - - - - - - 
 * local setup and teardown
 * - - - - - - - - - - - - - - - - - - - - - -
 */

int this_setup()
{
    etch_apr_mempool = g_apr_mempool;
    return 0;
}

int this_teardown()
{    
    return 0;
}


/* - - - - - - - - - - - - - - - - - - - - - - 
 * individual setup and teardown
 * - - - - - - - - - - - - - - - - - - - - - -
 */

int this_test_setup()
{
    int result = -1;

    do {
        result = 0;

    } while(0);

    return result;
}

int this_test_teardown()
{    

    return 0;
}

int g_is_automated_test, g_bytes_allocated;


/**
 * destroy_content_id_name()
 * passed a content pointer out of the hashtable, interprets pointer as etch_id_name,
 * frees the name string, and frees the etch_id_name shell.
 */
int destroy_content_id_name(void* content)
{
    etch_id_name*  idname = (etch_id_name*) content;
    return idname? idname->destroy(idname): -1;
    return 0;
}


/**
 * destroy_content_field()
 */
int destroy_content_field(void* content)
{
    etch_field* field = (etch_field*) content;
    return field? field->destroy(field): -1;
}


/**
 * destroy_content_type()
 */
int destroy_content_type(void* content)
{
    etch_type* type = (etch_type*) content;
    return type? type->destroy(type): -1;
}


/**
 * test_idname_as_key
 * tests that we can use etch_id_name (and etch_field and etch_type, since they
 * are etch_id_name typedefs), as hashkeys, and subsequently acccess the original
 * objects, individually clean up the keys, and ask hashtable to clean up the values.
 */
void test_idname_as_key_hashclean_values(void)
{
    etch_field*   my_field  = NULL;
    etch_type*    my_type   = NULL;
    etch_id_name* my_idname = NULL;

    const int id_name_size = sizeof(etch_id_name);
    const int field_size   = sizeof(etch_field);
    const int type_size    = sizeof(etch_type);

    etch_hashtable* myhashtab = NULL;  
    etch_hashitem   hashbucket;
    etch_hashitem*  myentry = &hashbucket; 

    wchar_t* name1 = L"name number one";  
    wchar_t* name2 = L"nombre numero dos";
    wchar_t* name3 = L"le troisieme nom";

    const size_t numElements1 = wcslen(name1);
    const size_t numElements2 = wcslen(name2);
    const size_t numElements3 = wcslen(name3);

    const size_t numBytes1 = sizeof(wchar_t) * numElements1;
    const size_t numBytes2 = sizeof(wchar_t) * numElements2;
    const size_t numBytes3 = sizeof(wchar_t) * numElements3;

    void* value1 = NULL, *value2 = NULL, *value3 = NULL;

    int result = 0, result1 = 0, result2 = 0, result3 = 0;
    unsigned bytes_allocated = 0;

    value1 = etch_malloc(numBytes1 + 2, 0);   
    value2 = etch_malloc(numBytes2 + 2, 0);  
    value3 = etch_malloc(numBytes3 + 2, 0);  
    wcscpy_s(value1, numElements1+1, name1);   
    wcscpy_s(value2, numElements2+1, name2);   
    wcscpy_s(value3, numElements3+1, name3);   

    myhashtab = new_hashtable(16);  
    myhashtab->is_readonly_keys   = TRUE;  /* keys will NOT be freed on destroy */
    myhashtab->is_readonly_values = FALSE; /* values WILL be freed on destroy */
    myhashtab->is_tracked_memory  = TRUE;  /* hashtable will use etch_free */
   
    my_idname = new_id_name(name1);
    my_field  = new_field(name2);
    my_type   = new_type(name3);  

    CU_ASSERT_PTR_NOT_NULL_FATAL(my_idname);
    CU_ASSERT_PTR_NOT_NULL_FATAL(my_field);
    CU_ASSERT_PTR_NOT_NULL_FATAL(my_type);

    /* ensure constructors populated the hash key */
    CU_ASSERT_NOT_EQUAL_FATAL(my_idname->hashkey,0);
    CU_ASSERT_NOT_EQUAL_FATAL(my_field->hashkey,0);
    CU_ASSERT_NOT_EQUAL_FATAL(my_type->hashkey,0);

    /* ensure constructors populated the wire id */
    CU_ASSERT_NOT_EQUAL_FATAL(my_idname->id,0);
    CU_ASSERT_NOT_EQUAL_FATAL(my_field->id,0);
    CU_ASSERT_NOT_EQUAL_FATAL(my_type->id,0);

    result = myhashtab->vtab->inserth(myhashtab->realtable, my_idname, value1, 0, 0);
    CU_ASSERT_EQUAL_FATAL(result,0);

    result = myhashtab->vtab->inserth(myhashtab->realtable, my_field, value2, 0, 0);
    CU_ASSERT_EQUAL_FATAL(result,0);

    result = myhashtab->vtab->inserth(myhashtab->realtable, my_type, value3, 0, 0);
    CU_ASSERT_EQUAL_FATAL(result,0);

    result = myhashtab->vtab->findh(myhashtab->realtable, my_idname->hashkey, myhashtab, &myentry);
    CU_ASSERT_EQUAL(result,0);
    CU_ASSERT_PTR_NOT_NULL(myentry->key);
    CU_ASSERT_PTR_NOT_NULL(myentry->value);
    result = destroy_content_id_name(myentry->key);
    CU_ASSERT_EQUAL(result,0);    

    result = myhashtab->vtab->findh(myhashtab->realtable, my_field->hashkey, myhashtab, &myentry);
    CU_ASSERT_EQUAL(result,0);
    CU_ASSERT_PTR_NOT_NULL(myentry->key);
    CU_ASSERT_PTR_NOT_NULL(myentry->value);
    result = destroy_content_field(myentry->key);
    CU_ASSERT_EQUAL(result,0);   

    result = myhashtab->vtab->findh(myhashtab->realtable, my_type->hashkey, myhashtab, &myentry);
    CU_ASSERT_EQUAL(result,0);
    CU_ASSERT_PTR_NOT_NULL(myentry->key);
    CU_ASSERT_PTR_NOT_NULL(myentry->value);
    result = destroy_content_type(myentry->key);
    CU_ASSERT_EQUAL(result,0);  

    /** above we looked up each item and freed memory for the id_name, field, and type keys,
     * but not for their values. when we created the map we specified is_readonly_keys, so the
     * map destructor will free memory for the value content, but not for the key content. */
    myhashtab->destroy(myhashtab);

    bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE);  /* verify all memory freed */
    CU_ASSERT_EQUAL(bytes_allocated, 0);  
    memtable_clear();  /* start fresh for next test */   
}


/**
 * test_idname_as_key
 * tests that we can use etch_id_name (and etch_field and etch_type, since they
 * are etch_id_name typedefs), as hashkeys, and subsequently acccess the original
 * objects and clean up both the keys and values.
 */
void test_idname_as_key_hashclean_none(void)
{
    etch_field*   my_field  = NULL;
    etch_type*    my_type   = NULL;
    etch_id_name* my_idname = NULL;

    const int id_name_size = sizeof(etch_id_name);
    const int field_size   = sizeof(etch_field);
    const int type_size    = sizeof(etch_type);

    etch_hashtable* myhashtab = NULL;  
    etch_hashitem   hashbucket;
    etch_hashitem*  myentry = &hashbucket; 

    wchar_t* name1 = L"name number one";  
    wchar_t* name2 = L"nombre numero dos";
    wchar_t* name3 = L"le troisieme nom";

    const size_t numElements1 = wcslen(name1);
    const size_t numElements2 = wcslen(name2);
    const size_t numElements3 = wcslen(name3);

    const size_t numBytes1 = sizeof(wchar_t) * numElements1;
    const size_t numBytes2 = sizeof(wchar_t) * numElements2;
    const size_t numBytes3 = sizeof(wchar_t) * numElements3;
    void* value1 = NULL, *value2 = NULL, *value3 = NULL;

    size_t actlen1 = 0, actlen2 = 0, actlen3 = 0;
    int result = 0, result1 = 0, result2 = 0, result3 = 0;
    unsigned bytes_allocated = 0;

    value1 = etch_malloc(numBytes1 + 2, 0);   
    value2 = etch_malloc(numBytes2 + 2, 0);  
    value3 = etch_malloc(numBytes3 + 2, 0);  
    wcscpy_s(value1, numElements1+1, name1);   
    wcscpy_s(value2, numElements2+1, name2);   
    wcscpy_s(value3, numElements3+1, name3);   

    actlen1 = wcslen(name1);  actlen2 = wcslen(name2); actlen3 = wcslen(name3);

    myhashtab = new_hashtable(16);  
    myhashtab->is_readonly_keys   = TRUE; /* keys will be freed on destroy  */
    myhashtab->is_readonly_values = TRUE; /* values will be freed on destroy */
    myhashtab->is_tracked_memory  = TRUE; /* hashtable will etch_free content */

    /* here we are creating id_name, field, and type objects using names allocated
     * on out local stack. therefore the cleanup parameters must be set to not free 
     * memory for the name part, or we will crash. note that name is part of the 
     * key structs, and is also the value of the hashed key/value pair, however 
     * we etch_malloc'ed memory for the values and copied our stack strings into it,
     * so we will want to free the value memory. we could ask the hashtable to do
     * so but we'll do it manually here instead.
     */
    my_idname = new_id_name(name1);
    my_field  = new_field(name2);
    my_type   = new_type(name3);

    CU_ASSERT_PTR_NOT_NULL_FATAL(my_idname);
    CU_ASSERT_PTR_NOT_NULL_FATAL(my_field);
    CU_ASSERT_PTR_NOT_NULL_FATAL(my_type);

   /* ensure constructors populated the hash key */
    CU_ASSERT_NOT_EQUAL_FATAL(my_idname->hashkey,0);
    CU_ASSERT_NOT_EQUAL_FATAL(my_field->hashkey,0);
    CU_ASSERT_NOT_EQUAL_FATAL(my_type->hashkey,0);

    /* ensure constructors populated the id (hash of name) */
    CU_ASSERT_NOT_EQUAL_FATAL(my_idname->id,0);
    CU_ASSERT_NOT_EQUAL_FATAL(my_field->id,0);
    CU_ASSERT_NOT_EQUAL_FATAL(my_type->id,0);

    result = myhashtab->vtab->inserth(myhashtab->realtable, my_idname, value1, 0, 0);
    CU_ASSERT_EQUAL_FATAL(result,0);

    result = myhashtab->vtab->inserth(myhashtab->realtable, my_field, value2, 0, 0);
    CU_ASSERT_EQUAL_FATAL(result,0);

    result = myhashtab->vtab->inserth(myhashtab->realtable, my_type, value3, 0, 0);
    CU_ASSERT_EQUAL_FATAL(result,0);

    result = myhashtab->vtab->findh(myhashtab->realtable, my_idname->hashkey, myhashtab, &myentry);
    CU_ASSERT_EQUAL(result,0);
    CU_ASSERT_PTR_NOT_NULL(myentry->key);
    CU_ASSERT_PTR_NOT_NULL(myentry->value);
    result = destroy_content_id_name(myentry->key);  
    CU_ASSERT_EQUAL(result,0);  
    etch_free(myentry->value); 

    result = myhashtab->vtab->findh(myhashtab->realtable, my_field->hashkey, myhashtab, &myentry);
    CU_ASSERT_EQUAL(result,0);
    CU_ASSERT_PTR_NOT_NULL(myentry->key);
    CU_ASSERT_PTR_NOT_NULL(myentry->value);
    result = destroy_content_field(myentry->key);  
    CU_ASSERT_EQUAL(result,0); 
    etch_free(myentry->value);  

    result = myhashtab->vtab->findh(myhashtab->realtable, my_type->hashkey, myhashtab, &myentry);
    CU_ASSERT_EQUAL(result,0);
    CU_ASSERT_PTR_NOT_NULL(myentry->key);
    CU_ASSERT_PTR_NOT_NULL(myentry->value);
    result = destroy_content_type(myentry->key);  
    CU_ASSERT_EQUAL(result,0); 
    etch_free(myentry->value);  

    myhashtab->destroy(myhashtab);  /* hashtable was asked to not free any content */

    bytes_allocated = etch_showmem(0, IS_DEBUG_CONSOLE);  /* verify all memory freed */
    CU_ASSERT_EQUAL(bytes_allocated, 0);  
    memtable_clear();  /* start fresh for next test */ 
}



int _tmain(int argc, _TCHAR* argv[])
{
    CU_pSuite pSuite = 0; char c=0; 
    if (CUE_SUCCESS != CU_initialize_registry()) return -1;
    g_is_automated_test = argc > 1 && 0 != wcscmp(argv[1], L"-a");
    pSuite = CU_add_suite("suite_hashing", init_suite, clean_suite);
    CU_set_output_filename("../test_hashing");
    etch_watch_id = 0; 

    CU_add_test(pSuite, "test hash id_name etc - auto-cleanup values", test_idname_as_key_hashclean_values);
    CU_add_test(pSuite, "test hash id_name etc - no auto-cleanup", test_idname_as_key_hashclean_none);

    if (g_is_automated_test)    
        CU_automated_run_tests();    
    else
    {   CU_basic_set_mode(CU_BRM_VERBOSE);
        CU_basic_run_tests();
    }

    if (!g_is_automated_test) { printf("any key ..."); while(!c) c = _getch(); wprintf(L"\n"); }     
    CU_cleanup_registry();
    return CU_get_error(); 
}

