/*
 *******************************************************************************
 * Copyright (C) 1996-2003, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/test/calendar/CalendarTest.java,v $ 
 * $Date: 2003/10/02 20:50:58 $ 
 * $Revision: 1.16 $
 *
 *****************************************************************************************
 */

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

import com.ibm.icu.dev.test.*;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Hashtable;
import java.util.Enumeration;

import com.ibm.icu.util.*;

/**
 * A base class for classes that test individual Calendar subclasses.
 * Defines various useful utility methods and constants
 */
public class CalendarTest extends TestFmwk {
    
    // Constants for use by subclasses, solely to save typing
    public final static int SUN = Calendar.SUNDAY;
    public final static int MON = Calendar.MONDAY;
    public final static int TUE = Calendar.TUESDAY;
    public final static int WED = Calendar.WEDNESDAY;
    public final static int THU = Calendar.THURSDAY;
    public final static int FRI = Calendar.FRIDAY;
    public final static int SAT = Calendar.SATURDAY;

    public final static int ERA     = Calendar.ERA;
    public final static int YEAR    = Calendar.YEAR;
    public final static int MONTH   = Calendar.MONTH;
    public final static int DATE    = Calendar.DATE;
    public final static int HOUR    = Calendar.HOUR;
    public final static int MINUTE  = Calendar.MINUTE;
    public final static int SECOND  = Calendar.SECOND;
    public final static int DOY     = Calendar.DAY_OF_YEAR;
    public final static int WOY     = Calendar.WEEK_OF_YEAR;
    public final static int WOM     = Calendar.WEEK_OF_MONTH;
    public final static int DOW     = Calendar.DAY_OF_WEEK;
    public final static int DOWM    = Calendar.DAY_OF_WEEK_IN_MONTH;
    
    public final static SimpleTimeZone UTC = new SimpleTimeZone(0, "GMT");

    private static final String[] FIELD_NAME = {
        "ERA", "YEAR", "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH",
        "DAY_OF_MONTH", "DAY_OF_YEAR", "DAY_OF_WEEK",
        "DAY_OF_WEEK_IN_MONTH", "AM_PM", "HOUR", "HOUR_OF_DAY",
        "MINUTE", "SECOND", "MILLISECOND", "ZONE_OFFSET",
        "DST_OFFSET", "YEAR_WOY", "DOW_LOCAL", "EXTENDED_YEAR",
        "JULIAN_DAY", "MILLISECONDS_IN_DAY",
        "IS_LEAP_MONTH" // (ChineseCalendar only)
    };

    public static final String fieldName(int f) {
        return (f>=0 && f<FIELD_NAME.length) ?
            FIELD_NAME[f] : ("<Field " + f + ">");
    }

    /**
     * Iterates through a list of calendar <code>TestCase</code> objects and
     * makes sure that the time-to-fields and fields-to-time calculations work
     * correnctly for the values in each test case.
     */
    public void doTestCases(TestCase[] cases, Calendar cal)
    {
        cal.setTimeZone(UTC);
        
        // Get a format to use for printing dates in the calendar system we're testing
        DateFormat format = DateFormat.getDateTimeInstance(cal, DateFormat.SHORT, -1, Locale.getDefault());

        final String pattern = (cal instanceof ChineseCalendar) ?
            "E MMl/dd/y G HH:mm:ss.S z" :
            "E, MM/dd/yyyy G HH:mm:ss.S z";
    
        ((SimpleDateFormat)format).applyPattern(pattern);

        // This format is used for printing Gregorian dates.
        DateFormat gregFormat = new SimpleDateFormat(pattern);
        gregFormat.setTimeZone(UTC);

        GregorianCalendar pureGreg = new GregorianCalendar(UTC);
        pureGreg.setGregorianChange(new Date(Long.MIN_VALUE));
        DateFormat pureGregFmt = new SimpleDateFormat("E M/d/yyyy G");
        pureGregFmt.setCalendar(pureGreg);
        
        // Now iterate through the test cases and see what happens
        for (int i = 0; i < cases.length; i++)
        {
            TestCase test = cases[i];
            
            //
            // First we want to make sure that the millis -> fields calculation works
            // test.applyTime will call setTime() on the calendar object, and
            // test.fieldsEqual will retrieve all of the field values and make sure
            // that they're the same as the ones in the testcase
            //
            test.applyTime(cal);
            if (!test.fieldsEqual(cal, this)) {
                errln("Fail: (millis=>fields) " +
                      gregFormat.format(test.getTime()) + " => " +
                      format.format(cal.getTime()) +
                      ", expected " + test);
            }

            //
            // If that was OK, check the fields -> millis calculation
            // test.applyFields will set all of the calendar's fields to 
            // match those in the test case.
            //
            cal.clear();
            test.applyFields(cal);
            if (!test.equals(cal)) {
                errln("Fail: (fields=>millis) " + test + " => " +
                      pureGregFmt.format(cal.getTime()) +
                      ", expected " + pureGregFmt.format(test.getTime()));
            }
        }
    }
    
    static public final boolean ROLL = true;
    static public final boolean ADD = false;
    
    /**
     * Process test cases for <code>add</code> and <code>roll</code> methods.
     * Each test case is an array of integers, as follows:
     * <ul>
     *  <li>0: input year
     *  <li>1:       month  (zero-based)
     *  <li>2:       day
     *  <li>3: field to roll or add to
     *  <li>4: amount to roll or add
     *  <li>5: result year
     *  <li>6:        month (zero-based)
     *  <li>7:        day
     * </ul>
     * For example:
     * <pre>
     *   //       input                add by          output
     *   //  year  month     day     field amount    year  month     day
     *   {   5759, HESHVAN,   2,     MONTH,   1,     5759, KISLEV,    2 },
     * </pre>
     *
     * @param roll  <code>true</code> or <code>ROLL</code> to test the <code>roll</code> method;
     *              <code>false</code> or <code>ADD</code> to test the <code>add</code method
     */
    public void doRollAdd(boolean roll, Calendar cal, int[][] tests)
    {
        String name = roll ? "rolling" : "adding";
        
        for (int i = 0; i < tests.length; i++) {
            int[] test = tests[i];

            cal.clear();
            if (cal instanceof ChineseCalendar) {
                cal.set(Calendar.EXTENDED_YEAR, test[0]);
                cal.set(Calendar.MONTH, test[1]);
                cal.set(Calendar.DAY_OF_MONTH, test[2]);
            } else {
                cal.set(test[0], test[1], test[2]);
            }
            double day0 = getJulianDay(cal);
            if (roll) {
                cal.roll(test[3], test[4]);
            } else {
                cal.add(test[3], test[4]);
            }
            int y = cal.get(cal instanceof ChineseCalendar ?
                            Calendar.EXTENDED_YEAR : YEAR);
            if (y != test[5] || cal.get(MONTH) != test[6]
                    || cal.get(DATE) != test[7])
            {
                errln("Fail: " + name + " "+ ymdToString(test[0], test[1], test[2])
                    + " (" + day0 + ")"
                    + " " + FIELD_NAME[test[3]] + " by " + test[4]
                    + ": expected " + ymdToString(test[5], test[6], test[7])
                    + ", got " + ymdToString(cal));
            } else if (isVerbose()) {
                logln("OK: " + name + " "+ ymdToString(test[0], test[1], test[2])
                    + " (" + day0 + ")"
                    + " " + FIELD_NAME[test[3]] + " by " + test[4]
                    + ": got " + ymdToString(cal));
            }
        }
    }

    /**
     * Test the functions getXxxMinimum() and getXxxMaximum() by marching a
     * test calendar 'cal' through 'numberOfDays' sequential days starting
     * with 'startDate'.  For each date, read a field value along with its
     * reported actual minimum and actual maximum.  These values are
     * checked against one another as well as against getMinimum(),
     * getGreatestMinimum(), getLeastMaximum(), and getMaximum().  We
     * expect to see:
     *
     * 1. minimum <= actualMinimum <= greatestMinimum <=
     *    leastMaximum <= actualMaximum <= maximum
     *
     * 2. actualMinimum <= value <= actualMaximum
     *
     * Note: In addition to outright failures, this test reports some
     * results as warnings.  These are not generally of concern, but they
     * should be evaluated by a human.  To see these, run this test in
     * verbose mode.
     * @param cal the calendar to be tested
     * @param fieldsToTest an array of field values to be tested, e.g., new
     * int[] { Calendar.MONTH, Calendar.DAY_OF_MONTH }.  It only makes
     * sense to test the day fields; the time fields are not tested by this
     * method.  If null, then test all standard fields.
     * @param startDate the first date to test
     * @param testDuration if positive, the number of days to be tested.
     * If negative, the number of seconds to run the test.
     */
    protected void doLimitsTest(Calendar cal, int[] fieldsToTest,
                                Date startDate, int testDuration) {
        GregorianCalendar greg = new GregorianCalendar();
        greg.setTime(startDate);
        logln("Start: " + startDate);

        if (fieldsToTest == null) {
            fieldsToTest = new int[] {
                Calendar.ERA, Calendar.YEAR, Calendar.MONTH,
                Calendar.WEEK_OF_YEAR, Calendar.WEEK_OF_MONTH,
                Calendar.DAY_OF_MONTH, Calendar.DAY_OF_YEAR,
                Calendar.DAY_OF_WEEK_IN_MONTH, Calendar.YEAR_WOY,
                Calendar.EXTENDED_YEAR
            };
        }

        // Keep a record of minima and maxima that we actually see.
        // These are kept in an array of arrays of hashes.
        Hashtable[][] limits = new Hashtable[fieldsToTest.length][2];
        Object nub = new Object(); // Meaningless placeholder

        // This test can run for a long time; show progress.
        long millis = System.currentTimeMillis();
        long mark = millis + 5000; // 5 sec
        millis -= testDuration * 1000; // stop time if testDuration<0

        for (int i=0;
             testDuration>0 ? i<testDuration
                            : System.currentTimeMillis()<millis;
             ++i) {
            if (System.currentTimeMillis() >= mark) {
                logln("(" + i + " days)");
                mark += 5000; // 5 sec
            }
            cal.setTimeInMillis(greg.getTimeInMillis());
            for (int j=0; j<fieldsToTest.length; ++j) {
                int f = fieldsToTest[j];
                int v = cal.get(f);
                int minActual = cal.getActualMinimum(f);
                int maxActual = cal.getActualMaximum(f);
                int minLow = cal.getMinimum(f);
                int minHigh = cal.getGreatestMinimum(f);
                int maxLow = cal.getLeastMaximum(f);
                int maxHigh = cal.getMaximum(f);

                // Fetch the hash for this field and keep track of the
                // minima and maxima.
                Hashtable[] h = limits[j];
                if (h[0] == null) {
                    h[0] = new Hashtable();
                    h[1] = new Hashtable();
                }
                h[0].put(new Integer(minActual), nub);
                h[1].put(new Integer(maxActual), nub);

                if (minActual < minLow || minActual > minHigh) {
                    errln("Fail: " + ymdToString(cal) +
                          " Range for min of " + FIELD_NAME[f] +
                          "=" + minLow + ".." + minHigh +
                          ", actual_min=" + minActual);
                }
                if (maxActual < maxLow || maxActual > maxHigh) {
                    errln("Fail: " + ymdToString(cal) +
                          " Range for max of " + FIELD_NAME[f] +
                          "=" + maxLow + ".." + maxHigh +
                          ", actual_max=" + maxActual);
                }
                if (v < minActual || v > maxActual) {
                    errln("Fail: " + ymdToString(cal) +
                          " " + FIELD_NAME[f] + "=" + v +
                          ", actual range=" + minActual + ".." + maxActual +
                          ", allowed=(" + minLow + ".." + minHigh + ")..(" +
                          maxLow + ".." + maxHigh + ")");
                }
            }
            greg.add(Calendar.DAY_OF_YEAR, 1);
        }

        // Check actual maxima and minima seen against ranges returned
        // by API.
        StringBuffer buf = new StringBuffer();
        for (int j=0; j<fieldsToTest.length; ++j) {
            int f = fieldsToTest[j];
            buf.setLength(0);
            buf.append(FIELD_NAME[f]);
            Hashtable[] h = limits[j];
            boolean fullRangeSeen = true;
            for (int k=0; k<2; ++k) {
                int rangeLow = (k==0) ?
                    cal.getMinimum(f) : cal.getLeastMaximum(f);
                int rangeHigh = (k==0) ?
                    cal.getGreatestMinimum(f) : cal.getMaximum(f);
                // If either the top of the range or the bottom was never
                // seen, then there may be a problem.
                if (h[k].get(new Integer(rangeLow)) == null ||
                    h[k].get(new Integer(rangeHigh)) == null) {
                    fullRangeSeen = false;
                }
                buf.append(k==0 ? " minima seen=(" : "; maxima seen=(");
                for (Enumeration e=h[k].keys(); e.hasMoreElements(); ) {
                    int v = ((Integer) e.nextElement()).intValue();
                    buf.append(" " + v);
                }
                buf.append(") range=" + rangeLow + ".." + rangeHigh);
            }
            if (fullRangeSeen) {
                logln("OK: " + buf.toString());
            } else {
                // This may or may not be an error -- if the range of dates
                // we scan over doesn't happen to contain a minimum or
                // maximum, it doesn't mean some other range won't.
                logln("Warning: " + buf.toString());
            }
        }

        logln("End: " + greg.getTime());
    }

    /**
     * Convert year,month,day values to the form "year/month/day".
     * On input the month value is zero-based, but in the result string it is one-based.
     */
    static public String ymdToString(int year, int month, int day) {
        return "" + year + "/" + (month+1) + "/" + day;
    }

    /**
     * Convert year,month,day values to the form "year/month/day".
     */
    static public String ymdToString(Calendar cal) {
        double day = getJulianDay(cal);
        if (cal instanceof ChineseCalendar) {
            return "" + cal.get(Calendar.EXTENDED_YEAR) + "/" +
                (cal.get(Calendar.MONTH)+1) +
                (cal.get(ChineseCalendar.IS_LEAP_MONTH)==1?"(leap)":"") + "/" +
                cal.get(Calendar.DATE) + " (" + day + ")";
        }
        return ymdToString(cal.get(Calendar.EXTENDED_YEAR),
                            cal.get(MONTH), cal.get(DATE)) +
                            " (" + day + ")";
    }

    static double getJulianDay(Calendar cal) {
        return (cal.getTime().getTime() - JULIAN_EPOCH) / DAY_MS;
    }

    static final double DAY_MS = 24*60*60*1000.0;
    static final long JULIAN_EPOCH = -210866760000000L;   // 1/1/4713 BC 12:00
}
