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

#include <time.h>
#include <string.h>
#include <limits.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"

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

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) if ((expected)==(actual)) { record_pass(); } else { record_fail(); OUT << action << " returned " << (actual) << " instead of " << (expected) << endl; pass=FALSE; }
#define CONFIRM_GE(actual,expected) if ((actual)>=(expected)) { record_pass(); } else { record_fail(); OUT << action << " returned " << (actual) << " instead of x >= " << (expected) << endl; pass=FALSE; }
#define CONFIRM_NE(actual,expected) if ((expected)!=(actual)) { record_pass(); } else { record_fail(); OUT << action << " returned " << (actual) << " instead of x != " << (expected) << endl; pass=FALSE; }

#define CONFIRM_UErrorCode(actual,expected) if ((expected)==(actual)) { record_pass(); } else { record_fail(); OUT << action << " returned " << u_errorName(actual) << " instead of " << u_errorName(expected) << endl; pass=FALSE; }

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

/**
 * 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++ = '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",       0,      U_ZERO_ERROR,             e_Root,      { TRUE, FALSE, FALSE }, { TRUE, FALSE, FALSE } },
    { "te",            0,      U_ZERO_ERROR,             e_te,           { FALSE, TRUE, FALSE }, { TRUE, TRUE, FALSE } },
    { "te_IN",         0,      U_ZERO_ERROR,             e_te_IN,        { FALSE, FALSE, TRUE }, { TRUE, TRUE, TRUE } },
    { "te_NE",         0,      U_USING_FALLBACK_ERROR,   e_te,           { FALSE, TRUE, FALSE }, { TRUE, TRUE, FALSE } },
    { "te_IN_NE",      0,      U_USING_FALLBACK_ERROR,   e_te_IN,        { FALSE, FALSE, TRUE }, { TRUE, TRUE, TRUE } },
    { "ne",            0,      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;
    for (int32_t i=0; i<sizeof(l); ++i) ((char*)&l)[i] = (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);
}

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

ResourceBundleTest::ResourceBundleTest()
: pass(0),
  fail(0),
  OUT(it_out)
{
    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()
{
}

void ResourceBundleTest::runIndexedTest( int32_t index, UBool exec, 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=IntlTest::getTestDirectory();
        uprv_strcpy(testdatapath, directory);
        uprv_strcat(testdatapath, "testdata");

        ResourceBundle  test1(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;
        UnicodeString   result2;

        result1 = *test1.getString("string_in_Root_te_te_IN", err);
        result2 = *test2.getString("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(U_ICU_VERSION) + strlen(version1)]; // + 1 for zero byte
        char *versionID2 = new char[1 + strlen(U_ICU_VERSION) + strlen(version2)]; // + 1 for zero byte

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

        strcpy(versionID2, U_ICU_VERSION);
        strcat(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");
    }
    {
        UErrorCode   err = U_ZERO_ERROR;
        const char   *directory;
        char testdatapath[256];
        Locale       locale("te", "IN");

        directory=IntlTest::getTestDirectory();
        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;

        result2 = *test2.getString("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");
    }
}

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

UBool
ResourceBundleTest::testTag(const char* frag,
                            UBool in_Root,
                            UBool in_te,
                            UBool in_te_IN)
{
    UBool pass=TRUE;

    // 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,row,col, actual_bundle;
    int32_t index;
    const char *directory;
    char testdatapath[256];

    directory=IntlTest::getTestDirectory();
    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);

        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(kERROR);

        const UnicodeString *t = theBundle.getString(tag, status);
        if(t != NULL) {
            string = *t;
        }

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

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

        CONFIRM_UErrorCode(status, expected_resource_status);

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

        CONFIRM_EQ(string, expected_string);

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

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

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

        int32_t count = kERROR_COUNT;
        status = U_ZERO_ERROR;
        const UnicodeString* array = theBundle.getStringArray(tag, count, status);
        CONFIRM_UErrorCode(status,expected_resource_status);

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

            for (j=0; j<count; ++j)
            {
                char buf[32];
                expected_string = base;
                expected_string += itoa(j,buf);
                CONFIRM_EQ(array[j],expected_string);
            }
        }
        else
        {
            CONFIRM_EQ(count,kERROR_COUNT);
            CONFIRM_EQ((int32_t)(unsigned long)array,(int32_t)0);
            count = 0;
        }

        //--------------------------------------------------------------------------
        // arrayItem

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

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

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

        //--------------------------------------------------------------------------
        // 2dArray

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

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


        int32_t row_count = kERROR_COUNT, column_count = kERROR_COUNT;
        status = U_ZERO_ERROR;
        const UnicodeString** array2d = theBundle.get2dArray(tag, row_count, column_count, status);
        CONFIRM_UErrorCode(status,expected_resource_status);

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

            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);
                }
            }
        }
        else
        {
            CONFIRM_EQ(row_count,kERROR_COUNT);
            CONFIRM_EQ(column_count,kERROR_COUNT);
            CONFIRM_EQ((int32_t)(unsigned long)array,(int32_t)0);
            row_count = column_count = 0;
        }

        //--------------------------------------------------------------------------
        // 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);

            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);
        }

        //--------------------------------------------------------------------------
        // 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);

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

            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();
                else
                    record_fail();
            }
        }
        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);
            }
            else
            {
                if (status != U_MISSING_RESOURCE_ERROR) {
                    count++;
                    expected_string = base;
                    expected_string += buf;
                    CONFIRM_EQ(string,expected_string);
                }
            }
        }
        CONFIRM_EQ(count, expected_count);
    }
    return pass;
}

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

