/***********************************************************************
 * COPYRIGHT: 
 * Copyright (c) 1997-2015, International Business Machines Corporation
 * and others. All Rights Reserved.
 ***********************************************************************/
 
#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

#include "unicode/datefmt.h"
#include "unicode/smpdtfmt.h"
#include "unicode/gregocal.h"
#include "dtfmtrtts.h"
#include "caltest.h"
#include "cstring.h"

#include <stdio.h>
#include <string.h>

// *****************************************************************************
// class DateFormatRoundTripTest
// *****************************************************************************

// Useful for turning up subtle bugs: Change the following to TRUE, recompile,
// and run while at lunch.
// Warning -- makes test run infinite loop!!!
#ifndef INFINITE
#define INFINITE 0
#endif

// Define this to test just a single locale
//#define TEST_ONE_LOC  "cs_CZ"

// If SPARSENESS is > 0, we don't run each exhaustive possibility.
// There are 24 total possible tests per each locale.  A SPARSENESS
// of 12 means we run half of them.  A SPARSENESS of 23 means we run
// 1 of them.  SPARSENESS _must_ be in the range 0..23.
int32_t DateFormatRoundTripTest::SPARSENESS = 0;
int32_t DateFormatRoundTripTest::TRIALS = 4;
int32_t DateFormatRoundTripTest::DEPTH = 5;

DateFormatRoundTripTest::DateFormatRoundTripTest() : dateFormat(0) {
}

DateFormatRoundTripTest::~DateFormatRoundTripTest() {
    delete dateFormat;
}

#define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break;

void 
DateFormatRoundTripTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* par )
{
    optionv = (par && *par=='v');
    switch (index) {
        CASE(0,TestDateFormatRoundTrip)
        CASE(1, TestCentury)
        default: name = ""; break;
    }
}

UBool 
DateFormatRoundTripTest::failure(UErrorCode status, const char* msg)
{
    if(U_FAILURE(status)) {
        errln(UnicodeString("FAIL: ") + msg + " failed, error " + u_errorName(status));
        return TRUE;
    }

    return FALSE;
}

UBool 
DateFormatRoundTripTest::failure(UErrorCode status, const char* msg, const UnicodeString& str)
{
    if(U_FAILURE(status)) {
        UnicodeString escaped;
        escape(str,escaped);
        errln(UnicodeString("FAIL: ") + msg + " failed, error " + u_errorName(status) + ", str=" + escaped);
        return TRUE;
    }

    return FALSE;
}

void DateFormatRoundTripTest::TestCentury()
{
    UErrorCode status = U_ZERO_ERROR;
    Locale locale("es_PA");
    UnicodeString pattern = "MM/dd/yy hh:mm:ss a z";
    SimpleDateFormat fmt(pattern, locale, status);
    if (U_FAILURE(status)) {
        dataerrln("Fail: construct SimpleDateFormat: %s", u_errorName(status));
        return;
    }
    UDate date[] = {-55018555891590.05, 0, 0};
    UnicodeString result[2];

    fmt.format(date[0], result[0]);
    date[1] = fmt.parse(result[0], status);
    fmt.format(date[1], result[1]);
    date[2] = fmt.parse(result[1], status);

    /* This test case worked OK by accident before.  date[1] != date[0],
     * because we use -80/+20 year window for 2-digit year parsing.
     * (date[0] is in year 1926, date[1] is in year 2026.)  result[1] set
     * by the first format call returns "07/13/26 07:48:28 p.m. PST",
     * which is correct, because DST was not used in year 1926 in zone
     * America/Los_Angeles.  When this is parsed, date[1] becomes a time
     * in 2026, which is "07/13/26 08:48:28 p.m. PDT".  There was a zone
     * offset calculation bug that observed DST in 1926, which was resolved.
     * Before the bug was resolved, result[0] == result[1] was true,
     * but after the bug fix, the expected result is actually
     * result[0] != result[1]. -Yoshito
     */
    /* TODO: We need to review this code and clarify what we really
     * want to test here.
     */
    //if (date[1] != date[2] || result[0] != result[1]) {
    if (date[1] != date[2]) {
        errln("Round trip failure: \"%S\" (%f), \"%S\" (%f)", result[0].getBuffer(), date[1], result[1].getBuffer(), date[2]);
    }
}

// ==

void DateFormatRoundTripTest::TestDateFormatRoundTrip() 
{
    UErrorCode status = U_ZERO_ERROR;

    getFieldCal = Calendar::createInstance(status);
    if (U_FAILURE(status)) {
        dataerrln("Fail: Calendar::createInstance: %s", u_errorName(status));
        return;
    }


    int32_t locCount = 0;
    const Locale *avail = DateFormat::getAvailableLocales(locCount);
    logln("DateFormat available locales: %d", locCount);
    if(quick) {
        SPARSENESS = 18;
        logln("Quick mode: only testing SPARSENESS = 18");
    }
    TimeZone *tz = TimeZone::createDefault();
    UnicodeString temp;
    logln("Default TimeZone:             " + tz->getID(temp));
    delete tz;

#ifdef TEST_ONE_LOC // define this to just test ONE locale.
    Locale loc(TEST_ONE_LOC);
    test(loc);
#if INFINITE
    for(;;) {
      test(loc);
    }
#endif

#else
# if INFINITE
    // Special infinite loop test mode for finding hard to reproduce errors
    Locale loc = Locale::getDefault();
    logln("ENTERING INFINITE TEST LOOP FOR Locale: " + loc.getDisplayName(temp));
    for(;;) 
        test(loc);
# else
    test(Locale::getDefault());

#if 1
    // installed locales
    for (int i=0; i < locCount; ++i) {
        test(avail[i]);
    }
#endif

#if 1
    // special locales
    int32_t jCount = CalendarTest::testLocaleCount();
    for (int32_t j=0; j < jCount; ++j) {
        test(Locale(CalendarTest::testLocaleID(j)));
    }
#endif

# endif
#endif

    delete getFieldCal;
}

static const char *styleName(DateFormat::EStyle s)
{
    switch(s)
    {
    case DateFormat::SHORT: return "SHORT";
    case DateFormat::MEDIUM: return "MEDIUM";
    case DateFormat::LONG: return "LONG";
    case DateFormat::FULL: return "FULL";
//  case DateFormat::DEFAULT: return "DEFAULT";
    case DateFormat::DATE_OFFSET: return "DATE_OFFSET";
    case DateFormat::NONE: return "NONE";
    case DateFormat::DATE_TIME: return "DATE_TIME";
    default: return "Unknown";
    }
}

void DateFormatRoundTripTest::test(const Locale& loc) 
{
    UnicodeString temp;
#if !INFINITE
    logln("Locale: " + loc.getDisplayName(temp));
#endif

    // Total possibilities = 24
    //  4 date
    //  4 time
    //  16 date-time
    UBool TEST_TABLE [24];//= new boolean[24];
    int32_t i = 0;
    for(i = 0; i < 24; ++i) 
        TEST_TABLE[i] = TRUE;

    // If we have some sparseness, implement it here.  Sparseness decreases
    // test time by eliminating some tests, up to 23.
    for(i = 0; i < SPARSENESS; ) {
        int random = (int)(randFraction() * 24);
        if (random >= 0 && random < 24 && TEST_TABLE[i]) {
            TEST_TABLE[i] = FALSE;
            ++i;
        }
    }

    int32_t itable = 0;
    int32_t style = 0;
    for(style = DateFormat::FULL; style <= DateFormat::SHORT; ++style) {
        if(TEST_TABLE[itable++]) {
            logln("Testing style " + UnicodeString(styleName((DateFormat::EStyle)style)));
            DateFormat *df = DateFormat::createDateInstance((DateFormat::EStyle)style, loc);
            if(df == NULL) {
              errln(UnicodeString("Could not DF::createDateInstance ") + UnicodeString(styleName((DateFormat::EStyle)style)) +      " Locale: " + loc.getDisplayName(temp));
            } else {
              test(df, loc);
              delete df;
            }
        }
    }
    
    for(style = DateFormat::FULL; style <= DateFormat::SHORT; ++style) {
        if (TEST_TABLE[itable++]) {
          logln("Testing style " + UnicodeString(styleName((DateFormat::EStyle)style)));
            DateFormat *df = DateFormat::createTimeInstance((DateFormat::EStyle)style, loc);
            if(df == NULL) {
              errln(UnicodeString("Could not DF::createTimeInstance ") + UnicodeString(styleName((DateFormat::EStyle)style)) + " Locale: " + loc.getDisplayName(temp));
            } else {
              test(df, loc, TRUE);
              delete df;
            }
        }
    }
    
    for(int32_t dstyle = DateFormat::FULL; dstyle <= DateFormat::SHORT; ++dstyle) {
        for(int32_t tstyle = DateFormat::FULL; tstyle <= DateFormat::SHORT; ++tstyle) {
            if(TEST_TABLE[itable++]) {
                logln("Testing dstyle" + UnicodeString(styleName((DateFormat::EStyle)dstyle)) + ", tstyle" + UnicodeString(styleName((DateFormat::EStyle)tstyle)) );
                DateFormat *df = DateFormat::createDateTimeInstance((DateFormat::EStyle)dstyle, (DateFormat::EStyle)tstyle, loc);
                if(df == NULL) {
                    dataerrln(UnicodeString("Could not DF::createDateTimeInstance ") + UnicodeString(styleName((DateFormat::EStyle)dstyle)) + ", tstyle" + UnicodeString(styleName((DateFormat::EStyle)tstyle))    + "Locale: " + loc.getDisplayName(temp));
                } else {
                    test(df, loc);
                    delete df;
                }
            }
        }
    }
}

void DateFormatRoundTripTest::test(DateFormat *fmt, const Locale &origLocale, UBool timeOnly) 
{
    UnicodeString pat;
    if(fmt->getDynamicClassID() != SimpleDateFormat::getStaticClassID()) {
        errln("DateFormat wasn't a SimpleDateFormat");
        return;
    }
    
    UBool isGregorian = FALSE;
    UErrorCode minStatus = U_ZERO_ERROR;
    if(fmt->getCalendar() == NULL) {
      errln((UnicodeString)"DateFormatRoundTripTest::test, DateFormat getCalendar() returns null for " + origLocale.getName());
      return;
    } 
    UDate minDate = CalendarTest::minDateOfCalendar(*fmt->getCalendar(), isGregorian, minStatus);
    if(U_FAILURE(minStatus)) {
      errln((UnicodeString)"Failure getting min date for " + origLocale.getName());
      return;
    } 
    //logln(UnicodeString("Min date is ") + fullFormat(minDate)  + " for " + origLocale.getName());

    pat = ((SimpleDateFormat*)fmt)->toPattern(pat);

    // NOTE TO MAINTAINER
    // This indexOf check into the pattern needs to be refined to ignore
    // quoted characters.  Currently, this isn't a problem with the locale
    // patterns we have, but it may be a problem later.

    UBool hasEra = (pat.indexOf(UnicodeString("G")) != -1);
    UBool hasZoneDisplayName = (pat.indexOf(UnicodeString("z")) != -1) || (pat.indexOf(UnicodeString("v")) != -1) 
        || (pat.indexOf(UnicodeString("V")) != -1);

    // Because patterns contain incomplete data representing the Date,
    // we must be careful of how we do the roundtrip.  We start with
    // a randomly generated Date because they're easier to generate.
    // From this we get a string.  The string is our real starting point,
    // because this string should parse the same way all the time.  Note
    // that it will not necessarily parse back to the original date because
    // of incompleteness in patterns.  For example, a time-only pattern won't
    // parse back to the same date.

    //try {
        for(int i = 0; i < TRIALS; ++i) {
            UDate *d                = new UDate    [DEPTH];
            UnicodeString *s    = new UnicodeString[DEPTH];

            if(isGregorian == TRUE) {
              d[0] = generateDate();
            } else {
              d[0] = generateDate(minDate);
            }

            UErrorCode status = U_ZERO_ERROR;

            // We go through this loop until we achieve a match or until
            // the maximum loop count is reached.  We record the points at
            // which the date and the string starts to match.  Once matching
            // starts, it should continue.
            int loop;
            int dmatch = 0; // d[dmatch].getTime() == d[dmatch-1].getTime()
            int smatch = 0; // s[smatch].equals(s[smatch-1])
            for(loop = 0; loop < DEPTH; ++loop) {
                if (loop > 0)  {
                    d[loop] = fmt->parse(s[loop-1], status);
                    failure(status, "fmt->parse", s[loop-1]+" in locale: " + origLocale.getName() + " with pattern: " + pat);
                    status = U_ZERO_ERROR; /* any error would have been reported */
                }

                s[loop] = fmt->format(d[loop], s[loop]);
                
                // For displaying which date is being tested
                //logln(s[loop] + " = " + fullFormat(d[loop]));
                
                if(s[loop].length() == 0) {
                  errln("FAIL: fmt->format gave 0-length string in " + pat + " with number " + d[loop] + " in locale " + origLocale.getName());
                }

                if(loop > 0) {
                    if(smatch == 0) {
                        UBool match = s[loop] == s[loop-1];
                        if(smatch == 0) {
                            if(match) 
                                smatch = loop;
                        }
                        else if( ! match) 
                            errln("FAIL: String mismatch after match");
                    }

                    if(dmatch == 0) {
                        // {sfb} watch out here, this might not work
                        UBool match = d[loop]/*.getTime()*/ == d[loop-1]/*.getTime()*/;
                        if(dmatch == 0) {
                            if(match) 
                                dmatch = loop;
                        }
                        else if( ! match) 
                            errln("FAIL: Date mismatch after match");
                    }

                    if(smatch != 0 && dmatch != 0) 
                        break;
                }
            }
            // At this point loop == DEPTH if we've failed, otherwise loop is the
            // max(smatch, dmatch), that is, the index at which we have string and
            // date matching.

            // Date usually matches in 2.  Exceptions handled below.
            int maxDmatch = 2;
            int maxSmatch = 1;
            if (dmatch > maxDmatch) {
                // Time-only pattern with zone information and a starting date in PST.
                if(timeOnly && hasZoneDisplayName) {
                    int32_t startRaw, startDst;
                    fmt->getTimeZone().getOffset(d[0], FALSE, startRaw, startDst, status);
                    failure(status, "TimeZone::getOffset");
                    // if the start offset is greater than the offset on Jan 1, 1970
                    // in PST, then need one more round trip.  There are two cases
                    // fall into this category.  The start date is 1) DST or
                    // 2) LMT (GMT-07:52:58).
                    if (startRaw + startDst > -28800000) {
                        maxDmatch = 3;
                        maxSmatch = 2;
                    }
                }
            }

            // String usually matches in 1.  Exceptions are checked for here.
            if(smatch > maxSmatch) { // Don't compute unless necessary
                UBool in0;
                // Starts in BC, with no era in pattern
                if( ! hasEra && getField(d[0], UCAL_ERA) == GregorianCalendar::BC)
                    maxSmatch = 2;
                // Starts in DST, no year in pattern
                else if((in0=fmt->getTimeZone().inDaylightTime(d[0], status)) && ! failure(status, "gettingDaylightTime") &&
                         pat.indexOf(UnicodeString("yyyy")) == -1)
                    maxSmatch = 2;
                // If we start not in DST, but transition into DST
                else if (!in0 &&
                         fmt->getTimeZone().inDaylightTime(d[1], status) && !failure(status, "gettingDaylightTime"))
                    maxSmatch = 2;
                // Two digit year with no time zone change,
                // unless timezone isn't used or we aren't close to the DST changover
                else if (pat.indexOf(UnicodeString("y")) != -1
                        && pat.indexOf(UnicodeString("yyyy")) == -1
                        && getField(d[0], UCAL_YEAR)
                            != getField(d[dmatch], UCAL_YEAR)
                        && !failure(status, "error status [smatch>maxSmatch]")
                        && ((hasZoneDisplayName
                         && (fmt->getTimeZone().inDaylightTime(d[0], status)
                                == fmt->getTimeZone().inDaylightTime(d[dmatch], status)
                            || getField(d[0], UCAL_MONTH) == UCAL_APRIL
                            || getField(d[0], UCAL_MONTH) == UCAL_OCTOBER))
                         || !hasZoneDisplayName)
                         )
                {
                    maxSmatch = 2;
                }
                // If zone display name is used, fallback format might be used before 1970
                else if (hasZoneDisplayName && d[0] < 0) {
                    maxSmatch = 2;
                }
                else if (timeOnly && !isGregorian && hasZoneDisplayName && maxSmatch == 1) {
                    int32_t startRaw, startDst;
                    fmt->getTimeZone().getOffset(d[1], FALSE, startRaw, startDst, status);
                    failure(status, "TimeZone::getOffset");
                    // If the calendar type is not Gregorian and the pattern is time only,
                    // the calendar implementation may use a date before 1970 as day 0.
                    // In this case, time zone offset of the default year might be
                    // different from the one at 1970-01-01 in PST and string match requires
                    // one more iteration.
                    if (startRaw + startDst != -28800000) {
                        maxSmatch = 2;
                    }
                }
            }

            /*
             * Special case for Japanese and Buddhist (could have large negative years)
             * Also, Hebrew calendar need help handling leap month.
             */
            if(dmatch > maxDmatch || smatch > maxSmatch) {
              const char *type = fmt->getCalendar()->getType();
              if(!strcmp(type,"japanese") || (!strcmp(type,"buddhist"))) {
                maxSmatch = 4;
                maxDmatch = 4;
              } else if(!strcmp(type,"hebrew")) {
                  maxSmatch = 3;
                  maxDmatch = 3;
                }
            }

            // Use @v to see verbose results on successful cases
            UBool fail = (dmatch > maxDmatch || smatch > maxSmatch);
            if (optionv || fail) {
                if (fail) {
                    errln(UnicodeString("\nFAIL: Pattern: ") + pat +
                          " in Locale: " + origLocale.getName());
                } else {
                    errln(UnicodeString("\nOk: Pattern: ") + pat +
                          " in Locale: " + origLocale.getName());
                }
                
                logln("Date iters until match=%d (max allowed=%d), string iters until match=%d (max allowed=%d)",
                      dmatch,maxDmatch, smatch, maxSmatch);

                for(int j = 0; j <= loop && j < DEPTH; ++j) {
                    UnicodeString temp;
                    FieldPosition pos(FieldPosition::DONT_CARE);
                    errln((j>0?" P> ":"    ") + fullFormat(d[j]) + " F> " +
                          escape(s[j], temp) + UnicodeString(" d=") + d[j] + 
                          (j > 0 && d[j]/*.getTime()*/==d[j-1]/*.getTime()*/?" d==":"") +
                          (j > 0 && s[j] == s[j-1]?" s==":""));
                }
            }
            delete[] d;
            delete[] s;
        }
    /*}
    catch (ParseException e) {
        errln("Exception: " + e.getMessage());
        logln(e.toString());
    }*/
}

const UnicodeString& DateFormatRoundTripTest::fullFormat(UDate d) {
    UErrorCode ec = U_ZERO_ERROR;
    if (dateFormat == 0) {
        dateFormat = new SimpleDateFormat((UnicodeString)"EEE MMM dd HH:mm:ss.SSS zzz yyyy G", ec);
        if (U_FAILURE(ec) || dateFormat == 0) {
            fgStr = "[FAIL: SimpleDateFormat constructor]";
            delete dateFormat;
            dateFormat = 0;
            return fgStr;
        }
    }
    fgStr.truncate(0);
    dateFormat->format(d, fgStr);
    return fgStr;
}

/**
 * Return a field of the given date
 */
int32_t DateFormatRoundTripTest::getField(UDate d, int32_t f) {
    // Should be synchronized, but we're single threaded so it's ok
    UErrorCode status = U_ZERO_ERROR;
    getFieldCal->setTime(d, status);
    failure(status, "getfieldCal->setTime");
    int32_t ret = getFieldCal->get((UCalendarDateFields)f, status);
    failure(status, "getfieldCal->get");
    return ret;
}

UnicodeString& DateFormatRoundTripTest::escape(const UnicodeString& src, UnicodeString& dst ) 
{
    dst.remove();
    for (int32_t i = 0; i < src.length(); ++i) {
        UChar c = src[i];
        if(c < 0x0080) 
            dst += c;
        else {
            dst += UnicodeString("[");
            char buf [8];
            sprintf(buf, "%#x", c);
            dst += UnicodeString(buf);
            dst += UnicodeString("]");
        }
    }

    return dst;
}

#define U_MILLIS_PER_YEAR (365.25 * 24 * 60 * 60 * 1000)

UDate DateFormatRoundTripTest::generateDate(UDate minDate)
{
  // Bring range in conformance to generateDate() below.
  if(minDate < (U_MILLIS_PER_YEAR * -(4000-1970))) {
    minDate = (U_MILLIS_PER_YEAR * -(4000-1970));
  }
  for(int i=0;i<8;i++) {
    double a = randFraction();
    
    // Range from (min) to  (8000-1970) AD
    double dateRange = (0.0 - minDate) + (U_MILLIS_PER_YEAR + (8000-1970));
    
    a *= dateRange;

    // Now offset from minDate
    a += minDate;
   
    // Last sanity check
    if(a>=minDate) {
      return a;
    }
  }
  return minDate;
}

UDate DateFormatRoundTripTest::generateDate() 
{
    double a = randFraction();
    
    // Now 'a' ranges from 0..1; scale it to range from 0 to 8000 years
    a *= 8000;
    
    // Range from (4000-1970) BC to (8000-1970) AD
    a -= 4000;
    
    // Now scale up to ms
    a *= 365.25 * 24 * 60 * 60 * 1000;

    //return new Date((long)a);
    return a;
}

#endif /* #if !UCONFIG_NO_FORMATTING */

//eof
