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

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "unicode/decimfmt.h"
#include "tsnmfmt.h"
#include <float.h>

static const char * formattableTypeName(Formattable::Type t)
{
  switch(t) {
  case Formattable::kDate: return "kDate";
  case Formattable::kDouble: return "kDouble";
  case Formattable::kLong: return "kLong";
  case Formattable::kString: return "kString";
  case Formattable::kArray: return "kArray";
  default: return "??unknown??";
  }
}

/**
 * This test does round-trip testing (format -> parse -> format -> parse -> etc.) of
 * NumberFormat.
 */
void IntlTestNumberFormat::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
{

    if (exec) logln((UnicodeString)"TestSuite NumberFormat");
    switch (index) {
        case 0: name = "createInstance"; 
            if (exec)
            {
                logln(name);
                fStatus = U_ZERO_ERROR;
                fFormat = NumberFormat::createInstance(fStatus);
                testFormat(/*par*/);
            }
            break;

        case 1: name = "DefaultLocale";
            if (exec) testLocale(/*par, */Locale::getDefault(), name);
            break;

        case 2: name = "testAvailableLocales"; 
            if (exec) {
                logln(name);
                testAvailableLocales(/*par*/);
            }
            break;

        case 3: name = "monsterTest";
            if (exec) {
                logln(name);
                monsterTest(/*par*/);
            }
            break;

        default: name = ""; break;
    }
}

void
IntlTestNumberFormat::testLocale(/* char* par, */const Locale& locale, const UnicodeString& localeName)
{
    const char* name;
    
    fLocale = locale;
    name = "Number test";
    logln((UnicodeString)name + " (" + localeName + ")");
    fStatus = U_ZERO_ERROR;
    fFormat = NumberFormat::createInstance(locale, fStatus);
    testFormat(/* par */);

    name = "Currency test";
    logln((UnicodeString)name + " (" + localeName + ")");
    fStatus = U_ZERO_ERROR;
    fFormat = NumberFormat::createCurrencyInstance(locale, fStatus);
    testFormat(/* par */);

    name = "Percent test";
    logln((UnicodeString)name + " (" + localeName + ")");
    fStatus = U_ZERO_ERROR;
    fFormat = NumberFormat::createPercentInstance(locale, fStatus);
    testFormat(/* par */);
}

double IntlTestNumberFormat::randDouble()
{
    // Assume 8-bit (or larger) rand values.  Also assume
    // that the system rand() function is very poor, which it always is.
    // Call srand(currentTime) in intltest to make it truly random.
    double d;
    uint32_t i;
    char* poke = (char*)&d;
    do {
        for (i=0; i < sizeof(double); ++i)
        {
            poke[i] = (char)(rand() & 0xFF);
        }
    } while (uprv_isNaN(d) || uprv_isInfinite(d)
        || !((-DBL_MAX < d && d < DBL_MAX) || (d < -DBL_MIN && DBL_MIN < d)));

    return d;
}

/*
 * Return a random uint32_t
 **/
uint32_t IntlTestNumberFormat::randLong()
{
    // Assume 8-bit (or larger) rand values.  Also assume
    // that the system rand() function is very poor, which it always is.
    // Call srand(currentTime) in intltest to make it truly random.
    uint32_t d;
    uint32_t i;
    char* poke = (char*)&d;
    for (i=0; i < sizeof(uint32_t); ++i)
    {
        poke[i] = (char)(rand() & 0xFF);
    }
    return d;
}


/* Make sure that we don't get something too large and multiply into infinity. */
double IntlTestNumberFormat::getSafeDouble(double smallerThanMax) {
    double it;
    do {
        it = randDouble();
    } while (-DBL_MAX/smallerThanMax > it || it > DBL_MAX/smallerThanMax);
    it *= smallerThanMax/10.0;
    return it;
}

void
IntlTestNumberFormat::testFormat(/* char* par */)
{
    if (U_FAILURE(fStatus))
    { 
        errln((UnicodeString)"**** FAIL: createXxxInstance failed.");
        if (fFormat != 0)
            errln("**** FAIL: Non-null format returned by createXxxInstance upon failure.");
        delete fFormat;
        fFormat = 0;
        return;
    }
                    
    if (fFormat == 0)
    {
        errln((UnicodeString)"**** FAIL: Null format returned by createXxxInstance.");
        return;
    }

    UnicodeString str;

    // Assume it's a DecimalFormat and get some info
    DecimalFormat *s = (DecimalFormat*)fFormat;
    logln((UnicodeString)"  Pattern " + s->toPattern(str));

#if defined(OS390) || defined(OS400)
    tryIt(-2.02147304840132e-68);
    tryIt(3.88057859588817e-68); // Test rounding when only some digits are shown because exponent is close to -maxfrac
    tryIt(-2.64651110485945e+65); // Overflows to +INF when shown as a percent
    tryIt(9.29526819488338e+64); // Ok -- used to fail?
#else
    tryIt(-2.02147304840132e-100);
    tryIt(3.88057859588817e-096); // Test rounding when only some digits are shown because exponent is close to -maxfrac
    tryIt(-2.64651110485945e+306); // Overflows to +INF when shown as a percent
    tryIt(9.29526819488338e+250); // Ok -- used to fail?
#endif

    // These PASS now, with the sprintf/atof based format-parse.

    // These fail due to round-off
    // The least significant digit drops by one during each format-parse cycle.
    // Both numbers DON'T have a round-off problem when multiplied by 100! (shown as %)
#ifdef OS390
    tryIt(-9.18228054496402e+64);
    tryIt(-9.69413034454191e+64);
#else
    tryIt(-9.18228054496402e+255);
    tryIt(-9.69413034454191e+273);
#endif

#ifndef OS390
    tryIt(1.234e-200);
    tryIt(-2.3e-168);

    tryIt(uprv_getNaN());
    tryIt(uprv_getInfinity());
    tryIt(-uprv_getInfinity());
#endif

    tryIt((int32_t)251887531);
    tryIt(5e-20 / 9);
    tryIt(5e20 / 9);
    tryIt(1.234e-50);
    tryIt(9.99999999999996);
    tryIt(9.999999999999996);

    tryIt((int32_t)INT32_MIN);
    tryIt((int32_t)INT32_MAX);
    tryIt((double)INT32_MIN);
    tryIt((double)INT32_MAX);
    tryIt((double)INT32_MIN - 1.0);
    tryIt((double)INT32_MAX + 1.0);

    tryIt(5.0 / 9.0 * 1e-20);
    tryIt(4.0 / 9.0 * 1e-20);
    tryIt(5.0 / 9.0 * 1e+20);
    tryIt(4.0 / 9.0 * 1e+20);

    tryIt(2147483647.);
    tryIt((int32_t)0);
    tryIt(0.0);
    tryIt((int32_t)1);
    tryIt((int32_t)10);
    tryIt((int32_t)100);
    tryIt((int32_t)-1);
    tryIt((int32_t)-10);
    tryIt((int32_t)-100);
    tryIt((int32_t)-1913860352);

    for (int32_t z=0; z<10; ++z)
    {
        double d = randFraction() * 2e10 - 1e10;
        tryIt(d);
    }

    double it = getSafeDouble(100000.0);

    tryIt(0.0);
    tryIt(it);
    tryIt((int32_t)0);
    tryIt(uprv_floor(it));
    tryIt((int32_t)randLong());

    // try again
    it = getSafeDouble(100.0);
    tryIt(it);
    tryIt(uprv_floor(it));
    tryIt((int32_t)randLong());

    // try again with very large numbers
    it = getSafeDouble(100000000000.0);
    tryIt(it);

    // try again with very large numbers
    // and without going outside of the int32_t range
    it = randFraction() * INT32_MAX;
    tryIt(it);
    tryIt((int32_t)uprv_floor(it));

    delete fFormat;
}

void 
IntlTestNumberFormat::tryIt(double aNumber)
{
    const int32_t DEPTH = 10;
    Formattable number[DEPTH];
    UnicodeString string[DEPTH];

    int32_t numberMatch = 0;
    int32_t stringMatch = 0;
    UBool dump = FALSE;
    int32_t i;
    for (i=0; i<DEPTH; ++i)
    {
        UErrorCode status = U_ZERO_ERROR;
        if (i == 0)
            number[i].setDouble(aNumber);
        else
            fFormat->parse(string[i-1], number[i], status);
        if (U_FAILURE(status))
        {
            errln("**** FAIL: Parse of " + string[i-1] + " failed.");
            dump = TRUE;
            break;
        }
        // Convert from long to double
        if (number[i].getType() == Formattable::kLong)
            number[i].setDouble(number[i].getLong());
        else if (number[i].getType() != Formattable::kDouble)
        {
            errln("**** FAIL: Parse of " + string[i-1]
                + " returned non-numeric Formattable, type " + UnicodeString(formattableTypeName(number[i].getType()))
                + ", Locale=" + UnicodeString(fLocale.getName())
                + ", longValue=" + number[i].getLong());
            dump = TRUE;
            break;
        }
        fFormat->format(number[i].getDouble(), string[i]);
        if (i > 0)
        {
            if (numberMatch == 0 && number[i] == number[i-1])
                numberMatch = i;
            else if (numberMatch > 0 && number[i] != number[i-1])
            {
                errln("**** FAIL: Numeric mismatch after match.");
                dump = TRUE;
                break;
            }
            if (stringMatch == 0 && string[i] == string[i-1])
                stringMatch = i;
            else if (stringMatch > 0 && string[i] != string[i-1])
            {
                errln("**** FAIL: String mismatch after match.");
                dump = TRUE;
                break;
            }
        }
        if (numberMatch > 0 && stringMatch > 0)
            break;
    }
    if (i == DEPTH)
        --i;

    if (stringMatch > 2 || numberMatch > 2)
    {
        errln("**** FAIL: No string and/or number match within 2 iterations.");
        dump = TRUE;
    }

    if (dump)
    {
        for (int32_t k=0; k<=i; ++k)
        {
            logln((UnicodeString)"" + k + ": " + number[k].getDouble() + " F> " +
                  string[k] + " P> ");
        }
    }
}

void 
IntlTestNumberFormat::tryIt(int32_t aNumber)
{
    Formattable number(aNumber);
    UnicodeString stringNum;
    UErrorCode status = U_ZERO_ERROR;

    fFormat->format(number, stringNum, status);
    if (U_FAILURE(status))
    {
        errln("**** FAIL: Formatting " + aNumber);
        return;
    }
    fFormat->parse(stringNum, number, status);
    if (U_FAILURE(status))
    {
        errln("**** FAIL: Parse of " + stringNum + " failed.");
        return;
    }
    if (number.getType() != Formattable::kLong)
    {
        errln("**** FAIL: Parse of " + stringNum
            + " returned non-long Formattable, type " + UnicodeString(formattableTypeName(number.getType()))
            + ", Locale=" + UnicodeString(fLocale.getName())
            + ", doubleValue=" + number.getDouble()
            + ", longValue=" + number.getLong()
            + ", origValue=" + aNumber
            );
    }
    if (number.getLong() != aNumber) {
        errln("**** FAIL: Parse of " + stringNum + " failed. Got:" + number.getLong()
            + " Expected:" + aNumber);
    }
}

void IntlTestNumberFormat::testAvailableLocales(/* char* par */)
{
    int32_t count = 0;
    const Locale* locales = NumberFormat::getAvailableLocales(count);
    logln((UnicodeString)"" + count + " available locales");
    if (locales && count)
    {
        UnicodeString name;
        UnicodeString all;
        for (int32_t i=0; i<count; ++i)
        {
            if (i!=0)
                all += ", ";
            all += locales[i].getName();
        }
        logln(all);
    }
    else
        errln((UnicodeString)"**** FAIL: Zero available locales or null array pointer");
}

void IntlTestNumberFormat::monsterTest(/* char* par */)
{
    const char *SEP = "============================================================\n";
    int32_t count;
    const Locale* locales = NumberFormat::getAvailableLocales(count);
    if (locales && count)
    {
        if (quick && count > 3) {
            logln("quick test: testing just 3 locales!");
            count = 3;
        }
        for (int32_t i=0; i<count; ++i)
        {
            UnicodeString name(locales[i].getName(), "");
            logln(SEP);
            testLocale(/* par, */locales[i], name);
        }
    }

    logln(SEP);
}

#endif /* #if !UCONFIG_NO_FORMATTING */
