/********************************************************************
 * COPYRIGHT: 
 * Copyright (c) 1997-2001, International Business Machines Corporation and
 * others. All Rights Reserved.
 ********************************************************************/

#include <stdlib.h>
#include <time.h>
#include <string.h>

#define RESTEST_HEAP_CHECK 0

#include "unicode/utypes.h"

#if defined(_WIN32) && !defined(__WINDOWS__)
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#endif

#include "cstring.h"
#include "unicode/unistr.h"
#include "unicode/resbund.h"
#include "restest.h"
#include <limits.h>

//***************************************************************************************

static const UnicodeString kERROR = UNICODE_STRING("ERROR", 5);
static const UChar kErrorUChars[] = { 0x45, 0x52, 0x52, 0x4f, 0x52, 0 };
static const int32_t kErrorLength = 5;
static const int32_t kERROR_COUNT = -1234567;

//***************************************************************************************

enum E_Where
{
    e_Root,
    e_te,
    e_te_IN,
    e_Where_count
};

//***************************************************************************************

#define CONFIRM_EQ(actual, expected, myAction) if ((expected)==(actual)) { record_pass(myAction); } else { record_fail(myAction + (UnicodeString)" returned " + (actual) + (UnicodeString)" instead of " + (expected) + "\n");}
#define CONFIRM_GE(actual, expected, myAction) if ((actual)>=(expected)) { record_pass(myAction); } else { record_fail(myAction + (UnicodeString)" returned " + (actual) + (UnicodeString)" instead of x >= " + (expected) + "\n");}
#define CONFIRM_NE(actual, expected, myAction) if ((expected)!=(actual)) { record_pass(myAction); } else { record_fail(myAction + (UnicodeString)" returned " + (actual) + (UnicodeString)" instead of x != " + (expected) + "\n");}

#define CONFIRM_UErrorCode(actual, expected, myAction) if ((expected)==(actual)) { record_pass(myAction); } else { record_fail(myAction + (UnicodeString)" returned " + u_errorName(actual) + " instead of " + u_errorName(expected) + "\n"); }

//***************************************************************************************

/**
 * Convert an integer, positive or negative, to a character string radix 10.
 */
char*
itoa(int32_t i, char* buf)
{
    char* result = buf;

    // Handle negative
    if (i < 0)
    {
        *buf++ = '-';
        i = -i;
    }

    // Output digits in reverse order
    char* p = buf;
    do
    {
        *p++ = (char)('0' + (i % 10));
        i /= 10;
    }
    while (i);
    *p-- = 0;

    // Reverse the string
    while (buf < p)
    {
        char c = *buf;
        *buf++ = *p;
        *p-- = c;
    }

    return result;
}



//***************************************************************************************

// Array of our test objects

struct
{
    const char* name;
    Locale *locale;
    UErrorCode expected_constructor_status;
    E_Where where;
    UBool like[e_Where_count];
    UBool inherits[e_Where_count];
}
param[] =
{
    // "te" means test
    // "IN" means inherits
    // "NE" or "ne" means "does not exist"

    { "root",       NULL,   U_ZERO_ERROR,             e_Root,      { TRUE, FALSE, FALSE }, { TRUE, FALSE, FALSE } },
    { "te",         NULL,   U_ZERO_ERROR,             e_te,        { FALSE, TRUE, FALSE }, { TRUE, TRUE, FALSE } },
    { "te_IN",      NULL,   U_ZERO_ERROR,             e_te_IN,     { FALSE, FALSE, TRUE }, { TRUE, TRUE, TRUE } },
    { "te_NE",      NULL,   U_USING_FALLBACK_ERROR,   e_te,        { FALSE, TRUE, FALSE }, { TRUE, TRUE, FALSE } },
    { "te_IN_NE",   NULL,   U_USING_FALLBACK_ERROR,   e_te_IN,     { FALSE, FALSE, TRUE }, { TRUE, TRUE, TRUE } },
    { "ne",         NULL,   U_USING_DEFAULT_ERROR,    e_Root,      { TRUE, FALSE, FALSE }, { TRUE, FALSE, FALSE } }
};

int32_t bundles_count = sizeof(param) / sizeof(param[0]);

//***************************************************************************************

/**
 * Return a random unsigned long l where 0N <= l <= ULONG_MAX.
 */

uint32_t
randul()
{
    static UBool initialized = FALSE;
    if (!initialized)
    {
        srand((unsigned)time(NULL));
        initialized = TRUE;
    }
    // Assume rand has at least 12 bits of precision
    uint32_t l = 0;
    for (uint32_t i=0; i<sizeof(l); ++i)
        ((char*)&l)[i] = (char)((rand() & 0x0FF0) >> 4);
    return l;
}

/**
 * Return a random double x where 0.0 <= x < 1.0.
 */
double
randd()
{
    return (double)(randul() / ULONG_MAX);
}

/**
 * Return a random integer i where 0 <= i < n.
 */
int32_t randi(int32_t n)
{
    return (int32_t)(randd() * n);
}

//***************************************************************************************

/*
 Don't use more than one of these at a time because of the Locale names
*/
ResourceBundleTest::ResourceBundleTest()
: pass(0),
  fail(0),
  OUT(it_out)
{
    if (param[5].locale == NULL) {
        param[0].locale = new Locale("root");
        param[1].locale = new Locale("te");
        param[2].locale = new Locale("te", "IN");
        param[3].locale = new Locale("te", "NE");
        param[4].locale = new Locale("te", "IN", "NE");
        param[5].locale = new Locale("ne");
    }
}

ResourceBundleTest::~ResourceBundleTest()
{
    if (param[5].locale) {
        int idx;
        for (idx = 0; idx < (int)(sizeof(param)/sizeof(param[0])); idx++) {
            delete param[idx].locale;
            param[idx].locale = NULL;
        }
    }
}

void ResourceBundleTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
{
    if (exec) logln("TestSuite ResourceBundleTest: ");
    switch (index) {
    case 0: name = "TestResourceBundles"; if (exec) TestResourceBundles(); break;
    case 1: name = "TestConstruction"; if (exec) TestConstruction(); break;

        default: name = ""; break; //needed to end loop
    }
}

//***************************************************************************************

void
ResourceBundleTest::TestResourceBundles()
{
#if defined(_WIN32) && !defined(__WINDOWS__)
#if defined(_DEBUG) && RESTEST_HEAP_CHECK
    /*
     * Set the debug-heap flag to keep freed blocks in the
     * heap's linked list - This will allow us to catch any
     * inadvertent use of freed memory
     */
    int tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
    tmpDbgFlag |= _CRTDBG_DELAY_FREE_MEM_DF;
    tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF;
    tmpDbgFlag |= _CRTDBG_CHECK_ALWAYS_DF;
    _CrtSetDbgFlag(tmpDbgFlag);

    _CrtMemState memstate;
    _CrtMemCheckpoint(&memstate);
    {
#endif
#endif

    testTag("only_in_Root", TRUE, FALSE, FALSE);
    testTag("only_in_te", FALSE, TRUE, FALSE);
    testTag("only_in_te_IN", FALSE, FALSE, TRUE);
    testTag("in_Root_te", TRUE, TRUE, FALSE);
    testTag("in_Root_te_te_IN", TRUE, TRUE, TRUE);
    testTag("in_Root_te_IN", TRUE, FALSE, TRUE);
    testTag("in_te_te_IN", FALSE, TRUE, TRUE);
    testTag("nonexistent", FALSE, FALSE, FALSE);
    OUT << "Passed: " << pass << "\nFailed: " << fail << endl;

#if defined(_WIN32) && !defined(__WINDOWS__)
#if defined(_DEBUG) && RESTEST_HEAP_CHECK
    }
    _CrtMemDumpAllObjectsSince(&memstate);

    /*
     * Set the debug-heap flag to keep freed blocks in the
     * heap's linked list - This will allow us to catch any
     * inadvertent use of freed memory
     */
    tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
    tmpDbgFlag |= _CRTDBG_DELAY_FREE_MEM_DF;
    tmpDbgFlag &= ~_CRTDBG_LEAK_CHECK_DF;
    tmpDbgFlag &= ~_CRTDBG_CHECK_ALWAYS_DF;
    _CrtSetDbgFlag(tmpDbgFlag);
#endif
#endif
}

void
ResourceBundleTest::TestConstruction()
{
    {
        UErrorCode   err = U_ZERO_ERROR;
        const char   *directory;
        char testdatapath[256];
        Locale       locale("te", "IN");

        directory=u_getDataDirectory();
        uprv_strcpy(testdatapath, directory);
        uprv_strcat(testdatapath, "testdata");

        ResourceBundle  test1((UnicodeString)testdatapath, err);
        ResourceBundle  test2(testdatapath, locale, err);
        //ResourceBundle  test1("c:\\icu\\icu\\source\\test\\testdata\\testdata", err);
        //ResourceBundle  test2("c:\\icu\\icu\\source\\test\\testdata\\testdata", locale, err);

        UnicodeString   result1(test1.getStringEx("string_in_Root_te_te_IN", err));
        UnicodeString   result2(test2.getStringEx("string_in_Root_te_te_IN", err));

        if (U_FAILURE(err)) {
            errln("Something threw an error in TestConstruction()");
            return;
        }

        logln("for string_in_Root_te_te_IN, default.txt had " + result1);
        logln("for string_in_Root_te_te_IN, te_IN.txt had " + result2);

        if (result1 != "ROOT" || result2 != "TE_IN")
            errln("Construction test failed; run verbose for more information");

        const char* version1;
        const char* version2;

        version1 = test1.getVersionNumber();
        version2 = test2.getVersionNumber();

        char *versionID1 = new char[1+strlen(version1)]; // + 1 for zero byte
        char *versionID2 = new char[1+ strlen(version2)]; // + 1 for zero byte

        strcpy(versionID1, "44");  // hardcoded, please change if the default.txt file or ResourceBundle::kVersionSeparater is changed.

        strcpy(versionID2, "55");  // hardcoded, please change if the te_IN.txt file or ResourceBundle::kVersionSeparater is changed.

        logln(UnicodeString("getVersionNumber on default.txt returned ") + version1);
        logln(UnicodeString("getVersionNumber on te_IN.txt returned ") + version2);

        if (strcmp(version1, versionID1) != 0 || strcmp(version2, versionID2) != 0)
            errln("getVersionNumber() failed");

        delete[] versionID1;
        delete[] versionID2;
    }
    {
        UErrorCode   err = U_ZERO_ERROR;
        const char   *directory;
        char testdatapath[256];
        Locale       locale("te", "IN");

        directory=u_getDataDirectory();
        uprv_strcpy(testdatapath, directory);
        uprv_strcat(testdatapath, "testdata");


        wchar_t* wideDirectory = new wchar_t[256];
        mbstowcs(wideDirectory, testdatapath, 256);
        //mbstowcs(wideDirectory, "c:\\icu\\icu\\source\\test\\testdata\\testdata", 256);

        ResourceBundle  test2(wideDirectory, locale, err);

        UnicodeString   result2(test2.getStringEx("string_in_Root_te_te_IN", err));

        if (U_FAILURE(err)) {
            errln("Something threw an error in TestConstruction()");
            return;
        }

        logln("for string_in_Root_te_te_IN, te_IN.txt had " + result2);

        if (result2 != "TE_IN")
            errln("Construction test failed; run verbose for more information");

        delete[] wideDirectory;
    }
}

//***************************************************************************************

UBool
ResourceBundleTest::testTag(const char* frag,
                            UBool in_Root,
                            UBool in_te,
                            UBool in_te_IN)
{
    int32_t failOrig = fail;

    // Make array from input params

    UBool is_in[] = { in_Root, in_te, in_te_IN };

    const char* NAME[] = { "ROOT", "TE", "TE_IN" };

    // Now try to load the desired items

    char tag[100];
    UnicodeString action;

    int32_t i,j,actual_bundle;
//    int32_t row,col;
    int32_t index;
    const char *directory;
    char testdatapath[256];

    directory=u_getDataDirectory();
    uprv_strcpy(testdatapath, directory);
    uprv_strcat(testdatapath, "testdata");

    for (i=0; i<bundles_count; ++i)
    {
        action = "Constructor for ";
        action += param[i].name;

        UErrorCode status = U_ZERO_ERROR;
        ResourceBundle theBundle( testdatapath, *param[i].locale, status);
        //ResourceBundle theBundle( "c:\\icu\\icu\\source\\test\\testdata\\testdata", *param[i].locale, status);
        CONFIRM_UErrorCode(status, param[i].expected_constructor_status, action);

        if(i == 5)
          actual_bundle = 0; /* ne -> default */
        else if(i == 3)
          actual_bundle = 1; /* te_NE -> te */
        else if(i == 4)
          actual_bundle = 2; /* te_IN_NE -> te_IN */
        else
          actual_bundle = i;


        UErrorCode expected_resource_status = U_MISSING_RESOURCE_ERROR;
        for (j=e_te_IN; j>=e_Root; --j)
        {
            if (is_in[j] && param[i].inherits[j])
            {
                if(j == actual_bundle) /* it's in the same bundle OR it's a nonexistent=default bundle (5) */
                  expected_resource_status = U_ZERO_ERROR;
                else if(j == 0)
                  expected_resource_status = U_USING_DEFAULT_ERROR;
                else
                  expected_resource_status = U_USING_FALLBACK_ERROR;
                
                break;
            }
        }

        UErrorCode expected_status;

        UnicodeString base;
        for (j=param[i].where; j>=0; --j)
        {
            if (is_in[j])
            {
                base = NAME[j];
                break;
            }
        }

        //--------------------------------------------------------------------------
        // string

        uprv_strcpy(tag, "string_");
        uprv_strcat(tag, frag);

        action = param[i].name;
        action += ".getString(";
        action += tag;
        action += ")";


        status = U_ZERO_ERROR;

        UnicodeString string(theBundle.getStringEx(tag, status));

        if(U_FAILURE(status)) {
            string.setTo(TRUE, kErrorUChars, kErrorLength);
        }

        CONFIRM_UErrorCode(status, expected_resource_status, action);

        UnicodeString expected_string = U_SUCCESS(status) ? base : kERROR;

        CONFIRM_EQ(string, expected_string, action);

        //--------------------------------------------------------------------------
        // array

        uprv_strcpy(tag, "array_");
        uprv_strcat(tag, frag);

        action = param[i].name;
        action += ".get(";
        action += tag;
        action += ")";

        status = U_ZERO_ERROR;
        ResourceBundle arrayBundle(theBundle.get(tag, status));
        CONFIRM_UErrorCode(status, expected_resource_status, action);
        int32_t count = arrayBundle.getSize();

        if (U_SUCCESS(status))
        {
            CONFIRM_GE(count, 1, action);

            for (j=0; j < count; ++j)
            {
                char buf[32];
                UnicodeString value(arrayBundle.getStringEx(j, status));
                expected_string = base;
                expected_string += itoa(j,buf);
                CONFIRM_EQ(value, expected_string, action);
            }

            action = param[i].name;
            action += ".getStringEx(";
            action += tag;
            action += ")";

            for (j=0; j<100; ++j)
            {
                index = count ? (randi(count * 3) - count) : (randi(200) - 100);
                status = U_ZERO_ERROR;
                string = kERROR;
                UnicodeString t(arrayBundle.getStringEx(index, status));
                expected_status = (index >= 0 && index < count) ? expected_resource_status : U_MISSING_RESOURCE_ERROR;
                CONFIRM_UErrorCode(status, expected_status, action);

                if (U_SUCCESS(status))
                {
                    char buf[32];
                    expected_string = base;
                    expected_string += itoa(index,buf);
                }
                else
                {
                    expected_string = kERROR;
                }
                CONFIRM_EQ(string, expected_string, action);
            }
        }
        else if (status != expected_resource_status)
        {
            record_fail("Error getting " + (UnicodeString)tag);
            return (UBool)(failOrig != fail);
        }


        // This is deprecated
        //--------------------------------------------------------------------------
        // 2dArray

/*
        uprv_strcpy(tag, "array_2d_");
        uprv_strcat(tag, frag);

        action = param[i].name;
        action += ".get2dArray(";
        action += tag;
        action += ")";


        const UnicodeString* array = theBundle.getStringArray(tag, count, status);
        CONFIRM_UErrorCode(status, expected_resource_status, action);
        int32_t row_count = kERROR_COUNT, column_count = kERROR_COUNT;
        int32_t row, col;
        status = U_ZERO_ERROR;
        const UnicodeString** array2d = theBundle.get2dArray(tag, row_count, column_count, status);
        CONFIRM_UErrorCode(status,expected_resource_status, action);

        if (U_SUCCESS(status))
        {
            CONFIRM_GE(row_count, 1, action);
            CONFIRM_GE(column_count, (int32_t)0, action);
            CONFIRM_NE((int32_t)(unsigned long)array, (int32_t)0, action);

            for (row=0; row<row_count; ++row)
            {
                for (col=0; col<column_count; ++col)
                {
                    char buf[32];
                    expected_string = base;
                    expected_string += itoa(row,buf);
                    expected_string += itoa(col,buf);
                    CONFIRM_EQ(array2d[row][col], expected_string, action);
                }
            }
        }
        else
        {
            CONFIRM_EQ(row_count, kERROR_COUNT, action);
            CONFIRM_EQ(column_count, kERROR_COUNT, action);
            CONFIRM_EQ((int32_t)(unsigned long)array, (int32_t)0, action);
            row_count = column_count = 0;
        }

        // This is deprecated
        //--------------------------------------------------------------------------
        // 2dArrayItem

        action = param[i].name;
        action += ".get2dArrayItem(";
        action += tag;
        action += ")";

        for (j=0; j<200; ++j)
        {
            row = row_count ? (randi(row_count * 3) - row_count) : (randi(200) - 100);
            col = column_count ? (randi(column_count * 3) - column_count) : (randi(200) - 100);
            status = U_ZERO_ERROR;
            string = kERROR;
            const UnicodeString *t = theBundle.get2dArrayItem(tag, row, col, status);
            if(t!=NULL) {
                string = *t;
            }
            expected_status = (row >= 0 && row < row_count && col >= 0 && col < column_count) ?
              expected_resource_status: U_MISSING_RESOURCE_ERROR;
            CONFIRM_UErrorCode(status, expected_status, action);

            if (U_SUCCESS(status))
            {
                char buf[32];
                expected_string = base;
                expected_string += itoa(row,buf);
                expected_string += itoa(col,buf);
            }
            else
            {
                expected_string = kERROR;
            }
            CONFIRM_EQ(string, expected_string, action);
        }

        //--------------------------------------------------------------------------
        // taggedArrayItem

        uprv_strcpy(tag, "tagged_array_");
        uprv_strcat(tag, frag);

        action = param[i].name;
        action += ".getTaggedArray(";
        action += tag;
        action += ")";

        UnicodeString*  tags = 0;
        UnicodeString*  items = 0;
        int32_t         expected_count;

        status = U_ZERO_ERROR;

        theBundle.getTaggedArray(tag, tags, items, expected_count, status);
        CONFIRM_UErrorCode(status, expected_resource_status, action);

        if (U_SUCCESS(status)) {
            CONFIRM_GE((int32_t)expected_count, (int32_t)0, action);
            CONFIRM_NE((int32_t)(unsigned long)tags, (int32_t)0, action);
            CONFIRM_NE((int32_t)(unsigned long)items, (int32_t)0, action);

            for (index = 0; index < expected_count; index++) {
                logln("tag = " + tags[index] + ", value = " + items[index]);
                if (tags[index].startsWith("tag") && items[index].startsWith(base))
                    record_pass(tags[index]);
                else
                    record_fail(tags[index]);
            }
        }
        else
            expected_count = 0;
        delete [] tags;
        delete [] items;

        //--------------------------------------------------------------------------
        // taggedArrayItem

        action = param[i].name;
        action += ".getTaggedArrayItem(";
        action += tag;
        action += ")";

        count = 0;
        for (index=-20; index<20; ++index)
        {
            char buf[32];
            UnicodeString item_tag("tag");
            item_tag += itoa(index,buf);

            status = U_ZERO_ERROR;
            string = kERROR;
            const UnicodeString *t = theBundle.getTaggedArrayItem(tag,item_tag,status);
            if(t!=NULL) {
                string = *t;
            }
            if (index < 0)
            {
                CONFIRM_UErrorCode(status, U_MISSING_RESOURCE_ERROR, action);
            }
            else
            {
                if (status != U_MISSING_RESOURCE_ERROR) {
                    count++;
                    expected_string = base;
                    expected_string += buf;
                    CONFIRM_EQ(string, expected_string, action);
                }
            }
        }
        CONFIRM_EQ(count, expected_count, action);
*/
    }

    return (UBool)(failOrig != fail);
}

void
ResourceBundleTest::record_pass(UnicodeString passMessage)
{
    logln(passMessage);
    ++pass;
}
void
ResourceBundleTest::record_fail(UnicodeString errMessage)
{
    err(errMessage);
    ++fail;
}
//eof

