
/*
********************************************************************
* COPYRIGHT: 
* (C) Copyright Taligent, Inc., 1997
* (C) Copyright International Business Machines Corporation, 1997 - 1998
* Licensed Material - Program-Property of IBM - All Rights Reserved. 
* US Government Users Restricted Rights - Use, duplication, or disclosure 
* restricted by GSA ADP Schedule Contract with IBM Corp. 
*
********************************************************************
*/

#include "utypes.h"
#include "tsdate.h"

#include "datefmt.h"
#include "smpdtfmt.h"

#include <math.h>

const double IntlTestDateFormat::ONEYEAR = 365.25 * ONEDAY; // Approximate

/**
 * This test does round-trip testing (format -> parse -> format -> parse -> etc.) of
 * DateFormat.
 */
// par is ignored throughout this file
void IntlTestDateFormat::runIndexedTest( int32_t index, bool_t exec, char* &name, char* par )
{
    if (exec) logln("TestSuite DateFormat");
    switch (index) {
        case 0: name = "Generic test (Default Locale)"; 
            if (exec) {
                logln(name);
                fFormat = DateFormat::createInstance();
                fTestName = "createInstance";
                fLimit = 3;
                testFormat( par );
            }
            break;
        case 1: name = "Default Locale";
            if (exec) {
                logln(name);
                testLocale(par, Locale::getDefault(), "Default Locale");
            }
            break;

        case 2: name = "Determine Available Locales"; 
            if (exec) {
                logln(name);
                testAvailableLocales(par);
            }
            break;

        case 3: name = "Test Available Locales"; 
            if (exec) {
                logln(name);
                monsterTest(par);
            }
            break;

        default: name = ""; break;
    }
}

void
IntlTestDateFormat::testLocale(char* par, const Locale& locale, const UnicodeString& localeName)
{
    DateFormat::EStyle timeStyle, dateStyle;
    
    // For patterns including only time information and a timezone, it may take
    // up to three iterations, since the timezone may shift as the year number
    // is determined.  For other patterns, 2 iterations should suffice.
    fLimit = 3;

    for(timeStyle = (DateFormat::EStyle)0; 
        timeStyle < (DateFormat::EStyle)4; 
        timeStyle = (DateFormat::EStyle) (timeStyle+1))
    {
        fTestName = (UnicodeString) "Time test " + (int32_t) timeStyle + " (" + localeName + ")";
        fFormat = DateFormat::createTimeInstance(timeStyle, locale);
        testFormat(par);
    }

    fLimit = 2;

    for(dateStyle = (DateFormat::EStyle)0; 
        dateStyle < (DateFormat::EStyle)4; 
        dateStyle = (DateFormat::EStyle) (dateStyle+1))
    {
        fTestName = (UnicodeString) "Date test " + (int32_t) dateStyle + " (" + localeName + ")";
        fFormat = DateFormat::createDateInstance(dateStyle, locale);
        testFormat(par);
    }

    for(dateStyle = (DateFormat::EStyle)0; 
        dateStyle < (DateFormat::EStyle)4; 
        dateStyle = (DateFormat::EStyle) (dateStyle+1))
    {
        for(timeStyle = (DateFormat::EStyle)0; 
            timeStyle < (DateFormat::EStyle)4; 
            timeStyle = (DateFormat::EStyle) (timeStyle+1))
        {
            fTestName = (UnicodeString) "DateTime test " + (int32_t) dateStyle + "/" + (int32_t) timeStyle + " (" + localeName + ")";
            fFormat = DateFormat::createDateTimeInstance(dateStyle, timeStyle, locale);
            testFormat(par);
        }
    }
}

void IntlTestDateFormat::testFormat(char *par)
{
    if (fFormat == 0)
    {
        errln("FAIL: DateFormat creation failed");
        return;
    }

    UDate now = Calendar::getNow();
    tryDate(0);
    tryDate(1278161801778.0);
    tryDate(now);
    // Shift 6 months into the future, AT THE SAME TIME OF DAY.
    // This will test the DST handling.
    tryDate(now + 6.0*30*ONEDAY);

    UDate limit = now * 10; // Arbitrary limit
    for (int32_t i=0; i<2; ++i) tryDate(icu_floor(randDouble() * limit));

    delete fFormat;
}

void
IntlTestDateFormat::describeTest()
{
    // Assume it's a SimpleDateFormat and get some info
    SimpleDateFormat *s = (SimpleDateFormat*)fFormat;
    UnicodeString str;
    logln(fTestName + " Pattern " + s->toPattern(str));
}

void IntlTestDateFormat::tryDate(UDate theDate)
{
    const int32_t DEPTH = 10;
    UDate date[DEPTH];
    UnicodeString string[DEPTH];

    int32_t dateMatch = 0;
    int32_t stringMatch = 0;
    bool_t dump = FALSE;
    int32_t i;
    for (i=0; i<DEPTH; ++i)
    {
        UErrorCode status = ZERO_ERROR;
        if (i == 0) date[i] = theDate;
        else date[i] = fFormat->parse(string[i-1], status);
        if (FAILURE(status))
        {
            describeTest();
            errln("********** FAIL: Parse of " + string[i-1] + " failed.");
            dump = TRUE;
            break;
        }
        fFormat->format(date[i], string[i]);
        if (i > 0)
        {
            if (dateMatch == 0 && date[i] == date[i-1]) dateMatch = i;
            else if (dateMatch > 0 && date[i] != date[i-1])
            {
                describeTest();
                errln("********** FAIL: Date 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])
            {
                describeTest();
                errln("********** FAIL: String mismatch after match.");
                dump = TRUE;
                break;
            }
        }
        if (dateMatch > 0 && stringMatch > 0) break;
    }
    if (i == DEPTH) --i;

    if (stringMatch > fLimit || dateMatch > fLimit)
    {
        describeTest();
        errln((UnicodeString)"********** FAIL: No string and/or date match within " + fLimit + " iterations.");
        dump = TRUE;
    }

    if (dump)
    {
        for (int32_t k=0; k<=i; ++k)
        {
            logln((UnicodeString)"" + k + ": " + date[k] + " F> " +
                  string[k] + " P> ");
        }
    }
}
    
// Return a random double from 0.01 to 1, inclusive
double IntlTestDateFormat::randDouble()
{
    // Assume 8-bit (or larger) rand values.  Also assume
    // that the system rand() function is very poor, which it always is.
    double d;
    int32_t i;
    do {
        for (i=0; i < sizeof(double); ++i)
        {
            char* poke = (char*)&d;
            poke[i] = (rand() & 0xFF);
        }
    } while (icu_isNaN(d) || icu_isInfinite(d));

    if (d < 0.0) d = -d;
    if (d > 0.0)
    {
        double e = icu_floor(icu_log10(d));
        if (e < -2.0) d *= icu_pow10(-e-2);
        else if (e > -1.0) d /= icu_pow10(e+1);
    }
    return d;
}

void IntlTestDateFormat::testAvailableLocales(char *par)
{
    int32_t count = 0;
    const Locale* locales = DateFormat::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(name);
        }
        logln(all);
    }
    else errln((UnicodeString)"********** FAIL: Zero available locales or null array pointer");
}

void IntlTestDateFormat::monsterTest(char *par)
{
    int32_t count;
    const Locale* locales = DateFormat::getAvailableLocales(count);
    if (locales && count)
    {
        if (quick && count > 2) {
            logln("quick test: testing just 2 locales!");
            count = 2;
        }
        for (int32_t i=0; i<count; ++i)
        {
            UnicodeString name;
            locales[i].getName(name);
            logln((UnicodeString)"Testing " + name + "...");
            testLocale(par, locales[i], name);
        }
    }
}
