// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/********************************************************************
 * COPYRIGHT: 
 * Copyright (c) 2003-2015, International Business Machines Corporation and
 * others. All Rights Reserved.
 ********************************************************************/
/*
* File hpmufn.c
*
*/

#include "unicode/utypes.h"
#include "unicode/putil.h"
#include "unicode/uclean.h"
#include "unicode/uchar.h"
#include "unicode/ures.h"
#include "cintltst.h"
#include "unicode/utrace.h"
#include <stdlib.h>
#include <string.h>

/**
 * This should align the memory properly on any machine.
 */
typedef union {
    long    t1;
    double  t2;
    void   *t3;
} ctest_AlignedMemory;

static void TestHeapFunctions(void);

void addHeapMutexTest(TestNode **root);


void
addHeapMutexTest(TestNode** root)
{
    addTest(root, &TestHeapFunctions,       "hpmufn/TestHeapFunctions"  );
}

static int32_t gMutexFailures = 0;

#define TEST_STATUS(status, expected) UPRV_BLOCK_MACRO_BEGIN { \
    if (status != expected) { \
        log_err_status(status, "FAIL at  %s:%d. Actual status = \"%s\";  Expected status = \"%s\"\n", \
                       __FILE__, __LINE__, u_errorName(status), u_errorName(expected)); gMutexFailures++; \
    } \
} UPRV_BLOCK_MACRO_END


#define TEST_ASSERT(expr) UPRV_BLOCK_MACRO_BEGIN { \
    if (!(expr)) { \
        log_err("FAILED Assertion \"" #expr "\" at  %s:%d.\n", __FILE__, __LINE__); \
        gMutexFailures++; \
    } \
} UPRV_BLOCK_MACRO_END


/*  These tests do cleanup and reinitialize ICU in the course of their operation.
 *    The ICU data directory must be preserved across these operations.
 *    Here is a helper function to assist with that.
 */
static char *safeGetICUDataDirectory() {
    const char *dataDir = u_getDataDirectory();  /* Returned string vanashes with u_cleanup */
    char *retStr = NULL;
    if (dataDir != NULL) {
        retStr = (char *)malloc(strlen(dataDir)+1);
        strcpy(retStr, dataDir);
    }
    return retStr;
}


    
/*
 *  Test Heap Functions.
 *    Implemented on top of the standard malloc heap.
 *    All blocks increased in size by 8 to 16 bytes, and the poiner returned to ICU is
 *       offset up by 8 to 16, which should cause a good heap corruption if one of our "blocks"
 *       ends up being freed directly, without coming through us.
 *    Allocations are counted, to check that ICU actually does call back to us.
 */
int    gBlockCount = 0;
const void  *gContext;

static void * U_CALLCONV myMemAlloc(const void *context, size_t size) {
    (void)context; // suppress compiler warnings about unused variable
    char *retPtr = (char *)malloc(size+sizeof(ctest_AlignedMemory));
    if (retPtr != NULL) {
        retPtr += sizeof(ctest_AlignedMemory);
    }
    gBlockCount ++;
    return retPtr;
}

static void U_CALLCONV myMemFree(const void *context, void *mem) {
    (void)context; // suppress compiler warnings about unused variable
    char *freePtr = (char *)mem;
    if (freePtr != NULL) {
        freePtr -= sizeof(ctest_AlignedMemory);
    }
    free(freePtr);
}



static void * U_CALLCONV myMemRealloc(const void *context, void *mem, size_t size) {
    (void)context; // suppress compiler warnings about unused variable
    char *p = (char *)mem;
    char *retPtr;

    if (p!=NULL) {
        p -= sizeof(ctest_AlignedMemory);
    }
    retPtr = realloc(p, size+sizeof(ctest_AlignedMemory));
    if (retPtr != NULL) {
        p += sizeof(ctest_AlignedMemory);
    }
    return retPtr;
}


static void TestHeapFunctions() {
    UErrorCode       status = U_ZERO_ERROR;
    UResourceBundle *rb     = NULL;
    char            *icuDataDir;
    UVersionInfo unicodeVersion = {0,0,0,0};

    icuDataDir = safeGetICUDataDirectory();   /* save icu data dir, so we can put it back
                                               *  after doing u_cleanup().                */


    /* Verify that ICU can be cleaned up and reinitialized successfully.
     *  Failure here usually means that some ICU service didn't clean up successfully,
     *  probably because some earlier test accidently left something open. */
    ctest_resetICU();

    /* Un-initialize ICU */
    u_cleanup();

    /* Can not set memory functions with NULL values */
    status = U_ZERO_ERROR;
    u_setMemoryFunctions(&gContext, NULL, myMemRealloc, myMemFree, &status);
    TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR);
    status = U_ZERO_ERROR;
    u_setMemoryFunctions(&gContext, myMemAlloc, NULL, myMemFree, &status);
    TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR);
    status = U_ZERO_ERROR;
    u_setMemoryFunctions(&gContext, myMemAlloc, myMemRealloc, NULL, &status);
    TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR);

    /* u_setMemoryFunctions() should work with null or non-null context pointer */
    status = U_ZERO_ERROR;
    u_setMemoryFunctions(NULL, myMemAlloc, myMemRealloc, myMemFree, &status);
    TEST_STATUS(status, U_ZERO_ERROR);
    u_setMemoryFunctions(&gContext, myMemAlloc, myMemRealloc, myMemFree, &status);
    TEST_STATUS(status, U_ZERO_ERROR);


    /* After reinitializing ICU, we can not set the memory funcs again. */
    status = U_ZERO_ERROR;
    u_setDataDirectory(icuDataDir);
    u_init(&status);
    TEST_STATUS(status, U_ZERO_ERROR);

    /* Doing ICU operations should cause allocations to come through our test heap */
    gBlockCount = 0;
    status = U_ZERO_ERROR;
    rb = ures_open(NULL, "es", &status);
    TEST_STATUS(status, U_ZERO_ERROR);
    if (gBlockCount == 0) {
        log_err("Heap functions are not being called from ICU.\n");
    }
    ures_close(rb);

    /* Cleanup should put the heap back to its default implementation. */
    ctest_resetICU();
    u_getUnicodeVersion(unicodeVersion);
    if (unicodeVersion[0] <= 0) {
        log_err("Properties doesn't reinitialize without u_init.\n");
    }
    status = U_ZERO_ERROR;
    u_init(&status);
    TEST_STATUS(status, U_ZERO_ERROR);

    /* ICU operations should no longer cause allocations to come through our test heap */
    gBlockCount = 0;
    status = U_ZERO_ERROR;
    rb = ures_open(NULL, "fr", &status);
    TEST_STATUS(status, U_ZERO_ERROR);
    if (gBlockCount != 0) {
        log_err("Heap functions did not reset after u_cleanup.\n");
    }
    ures_close(rb);
    free(icuDataDir);

    ctest_resetICU();
}


