/*
 *******************************************************************************
 * Copyright (C) 2001-2010, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */

/** 
 * Port From:   ICU4C v1.8.1 : format : DateFormatRoundTripTest
 * Source File: $ICU4CRoot/source/test/intltest/dtfmtrtts.cpp
 **/

package com.ibm.icu.dev.test.format;

import java.text.FieldPosition;
import java.text.ParseException;
import java.util.Date;
import java.util.Locale;
import java.util.Random;

import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.SimpleDateFormat;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.GregorianCalendar;
import com.ibm.icu.util.TimeZone;

/** 
 * Performs round-trip tests for DateFormat
 **/
public class DateFormatRoundTripTest extends com.ibm.icu.dev.test.TestFmwk {
    public boolean INFINITE = false;
    public boolean quick = true;
    private SimpleDateFormat dateFormat;
    private Calendar getFieldCal;
    private int SPARSENESS = 18;
    private int TRIALS = 4;
    private int DEPTH = 5;
    private Random ran;

    public static void main(String[] args) throws Exception {
        new DateFormatRoundTripTest().run(args);
    }
    
    public void TestDateFormatRoundTrip() {
        dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss.SSS zzz yyyy G");
        getFieldCal = Calendar.getInstance();
        ran = createRandom(); // use test framework's random seed

        final Locale[] avail = DateFormat.getAvailableLocales();
        int locCount = avail.length;
        logln("DateFormat available locales: " + locCount);
        if (quick) {
            if (locCount > 5)
                locCount = 5;
            logln("Quick mode: only testing first 5 Locales");
        }
        TimeZone tz = TimeZone.getDefault();
        logln("Default TimeZone:             " + tz.getID());
    
        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());
            for (;;) {
                _test(loc);
            }
        } else {        
            _test(Locale.getDefault());
            for (int i = 0; i < locCount; ++i) {
                _test(avail[i]);
            }
        }
    }
    
    public String styleName(int s) {
        switch (s) {
            case DateFormat.SHORT :
                return "SHORT";
            case DateFormat.MEDIUM :
                return "MEDIUM";
            case DateFormat.LONG :
                return "LONG";
            case DateFormat.FULL :
                return "FULL";
            default :
                return "Unknown";
        }
    }
    
    public void _test(Locale loc) {
        if (!INFINITE) {
            logln("Locale: " + loc.getDisplayName());
        }
        // Total possibilities = 24
        //  4 date
        //  4 time
        //  16 date-time
        boolean[] TEST_TABLE = new boolean[24];
        int 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; i++) {
            int random = (int) (ran.nextDouble() * 24);
            if (random >= 0 && random < 24 && TEST_TABLE[i]) {
                TEST_TABLE[random] = false;
            }
        }    
        
        int itable = 0;
        int style = 0;
        for (style = DateFormat.FULL; style <= DateFormat.SHORT; ++style) {
            if (TEST_TABLE[itable++]) {
                logln("Testing style " + styleName(style)); 
                DateFormat df = DateFormat.getDateInstance(style, loc); 
                _test(df, false);
            }
        }
    
        for (style = DateFormat.FULL; style <= DateFormat.SHORT; ++style) {
            if (TEST_TABLE[itable++]) {
                logln("Testing style " + styleName(style));
                DateFormat  df = DateFormat.getTimeInstance(style, loc); 
                _test(df, true);
            }
        }
    
        for (int dstyle = DateFormat.FULL; dstyle <= DateFormat.SHORT; ++dstyle) {
            for (int tstyle = DateFormat.FULL; tstyle <= DateFormat.SHORT; ++tstyle) {
                if (TEST_TABLE[itable++]) {
                    logln("Testing dstyle " + styleName(dstyle) + ", tstyle " + styleName(tstyle)); 
                    DateFormat df = DateFormat.getDateTimeInstance(dstyle, tstyle, loc); 
                    _test(df, false);
                }
            }
        }
    }
    
    public void _test(DateFormat fmt, boolean timeOnly) {
    
        if (!(fmt instanceof SimpleDateFormat)) {
            errln("DateFormat wasn't a SimpleDateFormat");
            return;
        }
    
        String pat = ((SimpleDateFormat) fmt).toPattern();
        logln(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.
    
        boolean hasEra = (pat.indexOf("G") != -1);
        boolean hasZoneDisplayName = (pat.indexOf("z") != -1) || (pat.indexOf("v") != -1) || (pat.indexOf("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) {
                Date[] d = new Date[DEPTH];
                String[] s = new String[DEPTH];
    
                d[0] = generateDate();
                
                // 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]);
                    }
    
                    s[loop] = fmt.format(d[loop]);
    
                    if (loop > 0) {
                        if (smatch == 0) {
                            boolean match = s[loop].equals(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
                            boolean 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 || smatch > maxSmatch) {
                    //If the Date is BC
                    if (!timeOnly && !hasEra && getField(d[0], Calendar.ERA) == GregorianCalendar.BC) {
                        maxDmatch = 3;
                        maxSmatch = 2;
                    }
                    if (hasZoneDisplayName &&
                            (fmt.getTimeZone().inDaylightTime(d[0])
                                    || fmt.getTimeZone().inDaylightTime(d[1])
                                    || d[0].getTime() < 0L /* before 1970 */)) {
                        maxSmatch = 2;
                        if (timeOnly) {
                            maxDmatch = 3;
                        }
                    }
                }
                    
                if (dmatch > maxDmatch || smatch > maxSmatch) {
                    SimpleDateFormat sdf = new SimpleDateFormat("EEEE, MMMM d, yyyy HH:mm:ss, z G", Locale.US);
                    logln("Date = " + sdf.format(d[0]) + "; ms = " + d[0].getTime());
                    logln("Dmatch: " + dmatch + " maxD: " + maxDmatch + " Smatch:" + smatch + " maxS:" + maxSmatch);
                    for (int j = 0; j <= loop && j < DEPTH; ++j) {
                        StringBuffer temp = new StringBuffer("");
                        FieldPosition pos = new FieldPosition(0);
                        logln((j > 0 ? " P> " : "    ") + dateFormat.format(d[j], temp, pos) 
                            + " F> " + s[j] + (j > 0 && d[j].getTime() == d[j - 1].getTime() ? " d==" : "")
                            + (j > 0 && s[j].equals(s[j - 1]) ? " s==" : ""));
                    }
                    errln("Pattern: " + pat + " failed to match" + "; ms = " + d[0].getTime());
                }
            }
        } catch (ParseException e) {
            errln("Exception: " + e.getMessage());
            logln(e.toString());
        }
    }
    
    public int getField(Date d, int f) {
        getFieldCal.setTime(d);
        int ret = getFieldCal.get(f);
        return ret;
    }
    
    public Date generateDate() {
        double a = ran.nextDouble();
        // 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);
    }
}
