//##header J2SE15
//#if defined(FOUNDATION10) || defined(J2SE13)
//#else
/*
 *******************************************************************************
 * Copyright (C) 2002-2007, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
*/
package com.ibm.icu.dev.test.timezone;

import java.util.ArrayList;
import java.util.Date;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.Iterator;

import java.text.DateFormat;
import java.text.NumberFormat;

import com.ibm.icu.dev.test.*;
import com.ibm.icu.dev.test.util.BagFormatter;
import com.ibm.icu.util.TimeZone;


/**
 * Class for testing TimeZones for consistency
 * @author Davis
 * 
 */
public class TimeZoneAliasTest extends TestFmwk {
    
    public static void main(String[] args) throws Exception {
        new TimeZoneAliasTest().run(args);
    }
    
    /**
     * There are two things to check aliases for:<br>
     * 1. the alias set must be uniform: if a isAlias b, then aliasSet(a) == aliasSet(b)<br>
     * 2. all aliases must have the same offsets
      */
    public void TestAliases() {
        if (skipIfBeforeICU(3,0,0)) return;
        Zone.Seconds seconds = new Zone.Seconds();
        for (Iterator it = Zone.getZoneSet().iterator(); it.hasNext(); ) {
            Zone zone = (Zone)it.next();
            String id = zone.id;
            if (id.indexOf('/') < 0 && (id.endsWith("ST") || id.endsWith("DT"))) {
                if (zone.minRecentOffset != zone.maxRecentOffset) {
                    errln(
                        "Standard or Daylight Time not constant: " + id 
                        + ": " + Zone.formatHours(zone.minRecentOffset)
                        + " != " + Zone.formatHours(zone.maxRecentOffset));
                }
            }
            Set aliases = zone.getPurportedAliases();
            Set aliasesSet = new TreeSet(aliases);
            aliasesSet.add(id); // for comparison
            Iterator aliasIterator = aliases.iterator();
            while (aliasIterator.hasNext()) {
                String otherId = (String)aliasIterator.next();
                Zone otherZone = Zone.make(otherId);
                Set otherAliases = otherZone.getPurportedAliases();
                otherAliases.add(otherId); // for comparison
                if (!aliasesSet.equals(otherAliases)) {
                    errln(
                        "Aliases Unsymmetric: "
                        + id + " => " + Zone.bf.join(aliasesSet)
                        + "; " 
                        + otherId + " => " + Zone.bf.join(otherAliases));
                }
                if (zone.findOffsetOrdering(otherZone, seconds) != 0) {
                    errln("Aliases differ: " + id + ", " + otherId
                         + " differ at " + seconds);
                }
            }
        }
    }
    
    /**
     * We check to see that every timezone that is not an alias is actually different!
     */
    public void TestDifferences() {
        if (skipIfBeforeICU(3,0,0)) return;
        Zone last = null;
        Zone.Seconds diffDate = new Zone.Seconds();        
        for (Iterator it = Zone.getZoneSet().iterator(); it.hasNext();) {
            Zone testZone = (Zone)it.next();
            if (last != null) {
                String common = testZone + "\tvs " + last + ":\t";
                int diff = testZone.findOffsetOrdering(last, diffDate);
                if (diff != 0) {
                    logln("\t" + common + "difference at: " + diffDate 
                        + ", " + Zone.formatHours(diff) + "hr");
                } else if (testZone.isRealAlias(last)) {
                    logln("\t" + common + "alias, no difference");
                } else {
                    errln(common + "NOT ALIAS BUT NO DIFFERENCE!");
                }
            }
            last = testZone;
        }
    }
    
    /**
     * Utility for printing out zones to be translated.
     */
    public static void TestGenerateZones() {
        int count = 1;
        for (Iterator it = Zone.getUniqueZoneSet().iterator(); it.hasNext();) {
            Zone zone = (Zone)it.next();
            System.out.println(zone.toString(count++));
        }
    }
    
    /** Utility; ought to be someplace common
     */
    /*
    static String join(Collection c, String separator) {
        StringBuffer result = new StringBuffer();
        boolean isFirst = true;
        for (Iterator it = c.iterator(); it.hasNext(); ) {
            if (!isFirst) result.append(separator);
            else isFirst = false;
            result.append(it.next().toString());
        }
        return result.toString();
    }
    */
        
    /**
     * The guts is in this subclass. It sucks in all the data from the zones,
     * and analyses it. It constructs some mappings for the unique ids,
     * etc.<br>
     * The main tricky bit is that for performance it pre-analyses all zones
     * for inflections points; the points in time where the offset changes.
     * The zones can then be sorted by those points, which allows us to
     * avoid expensive comparisons.
     * @author Davis
     */
    static class Zone implements Comparable {
        // class fields
        static private final BagFormatter bf = new BagFormatter().setSeparator(", ");
        static private final DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, Locale.US);
        static private final NumberFormat nf = NumberFormat.getInstance(Locale.US);
        static private final long HOUR = 1000*60*60;
        static private final double DHOUR = HOUR;
        static private final long DAY = 24*HOUR;
        static private final long GROSS_PERIOD = 30*DAY;
        static private final long EPSILON = HOUR/4;
        static private final int currentYear = new GregorianCalendar().get(Calendar.YEAR);
        static private final long endDate = getDate((currentYear+1),0,1).getTime();
        static private final long endDate2 = getDate((currentYear+1),6,1).getTime();
        static private final long recentLimit = getDate((currentYear-1),6,1).getTime();
        static private final long startDate = getDate(1905,0,1).getTime();
        
        static private final Map idToZone = new HashMap();
        static private final Set zoneSet = new TreeSet();
        static private final Set uniqueZoneSet = new TreeSet();
        static private final Map idToRealAliases = new HashMap();

        // build everything once.
        static {
            String [] foo = TimeZone.getAvailableIDs();
            for (int i = 0; i < foo.length; ++i) {
                zoneSet.add(Zone.make(foo[i]));
            }
            Zone last = null;
            Zone.Seconds diffDate = new Zone.Seconds();
            String lastUnique = "";      
            for (Iterator it = Zone.getZoneSet().iterator(); it.hasNext();) {
                Zone testZone = (Zone)it.next();
                if (last == null) {
                    uniqueZoneSet.add(testZone);
                    lastUnique = testZone.id;
                } else {
                    int diff = testZone.findOffsetOrdering(last, diffDate);
                    if (diff != 0) {
                        uniqueZoneSet.add(testZone);
                        lastUnique = testZone.id;
                    } else {
                        Set aliases = (Set)idToRealAliases.get(lastUnique);
                        if (aliases == null) {
                            aliases = new TreeSet();
                            idToRealAliases.put(lastUnique, aliases);
                        }
                        aliases.add(testZone.id);
                    }
                }
                last = testZone;
            }
        }
        
        static public Set getZoneSet() {
            return zoneSet;
        }
        
        public static Set getUniqueZoneSet() {
            return uniqueZoneSet;
        }

        static public Zone make(String id) {
            Zone result = (Zone)idToZone.get(id);
            if (result != null) return result;
            result = new Zone(id);
            idToZone.put(id, result);
            return result;
        }
        
        static public String formatHours(int hours) {
            return nf.format(hours/DHOUR);
        }
        
        // utility class for date return, because Date is clunky.
        public static class Seconds {
            public long seconds = Long.MIN_VALUE;
            public String toString() {
                if (seconds == Long.MIN_VALUE) return "n/a";
                return df.format(new Date(seconds));
            }
        }
        
        // instance fields
        // we keep min/max offsets not only over all time (that we care about)
        // but also separate ones for recent years.
        private String id;
        private TimeZone zone;
        // computed below
        private int minOffset;
        private int maxOffset;
        private int minRecentOffset;
        private int maxRecentOffset;
        private List inflectionPoints = new ArrayList();
        private Set purportedAliases = new TreeSet();
    
        private Zone(String id) { // for interal use only; use make instead!
            zone = TimeZone.getTimeZone(id);
            this.id = id;
            
            // get aliases
            int equivCount = TimeZone.countEquivalentIDs(id);
            for (int j = 0; j < equivCount; ++j) {
                String altID = TimeZone.getEquivalentID(id, j);
                if (altID.equals(id)) continue;
                purportedAliases.add(altID);
            }

            // find inflexion points; times where the offset changed
            long lastDate = endDate;
            if (zone.getOffset(lastDate) < zone.getOffset(endDate2)) lastDate = endDate2;
            maxRecentOffset = minRecentOffset = minOffset = maxOffset = zone.getOffset(lastDate);

            inflectionPoints.add(new Long(lastDate));
            int lastOffset = zone.getOffset(endDate);
            long lastInflection = endDate;
            
            // we do a gross search, then narrow in when we find a difference from the last one
            for (long currentDate = endDate; currentDate >= startDate; currentDate -= GROSS_PERIOD) {
                int currentOffset = zone.getOffset(currentDate);
                if (currentOffset != lastOffset) { // Binary Search
                    if (currentOffset < minOffset) minOffset = currentOffset;
                    if (currentOffset > maxOffset) maxOffset = currentOffset;
                    if (lastInflection >= recentLimit) {
                        if (currentOffset < minRecentOffset) minRecentOffset = currentOffset;
                        if (currentOffset > maxRecentOffset) maxRecentOffset = currentOffset;
                    }
                    long low = currentDate;
                    long high = lastDate;
                    while (low - high > EPSILON) {
                        long mid = (high + low)/2;
                        int midOffset = zone.getOffset(mid);
                        if (midOffset == low) {
                            low = mid;
                        } else {
                            high = mid;
                        }
                    }
                    inflectionPoints.add(new Long(low));
                    lastInflection = low;
                }
                lastOffset = currentOffset;
            }
            inflectionPoints.add(new Long(startDate)); // just to cap it off for comparisons.
        }
        
        // we assume that places will not convert time zones then back within one day
        // so we go first by half
        public int findOffsetOrdering(Zone other, Seconds dateDiffFound) {
            //System.out.println("-diff: " + id + "\t" + other.id);
            int result = 0;
            long seconds = 0;
            int min = inflectionPoints.size();
            if (other.inflectionPoints.size() < min) min = other.inflectionPoints.size();
            main:
            {
                for (int i = 0; i < min; ++i) {
                    long myIP = ((Long)inflectionPoints.get(i)).longValue();
                    long otherIP = ((Long)other.inflectionPoints.get(i)).longValue();
                    if (myIP > otherIP) { // take lowest, for transitivity (semi)
                        long temp = myIP;
                        myIP = otherIP;
                        otherIP = temp;
                    }
                    result = zone.getOffset(myIP) - other.zone.getOffset(myIP);
                    if (result != 0) {
                        seconds = myIP;
                        break main;
                    } 
                    if (myIP == otherIP) continue; // test other if different
                    myIP = otherIP;
                    result = zone.getOffset(myIP) - other.zone.getOffset(myIP);
                    if (result != 0) {
                        seconds = myIP;
                        break main;
                    } 
                }
                // if they are equal so far, we don't care about the rest
                result = 0;
                seconds = Long.MIN_VALUE;
                break main;
            }
            //System.out.println("+diff: " + (result/HOUR) + "\t" + dateDiffFound);
            if (dateDiffFound != null) dateDiffFound.seconds = seconds;
            return result;
        }
        
        // internal buffer to avoid creation all the time.
        private Seconds diffDateReturn = new Seconds();
        
        public int compareTo(Object o) {
            Zone other = (Zone)o;
            // first order by max and min offsets
            // min will usually correspond to standard time, max to daylight
            // unless there have been historical shifts
            if (minRecentOffset < other.minRecentOffset) return -1;
            if (minRecentOffset > other.minRecentOffset) return 1;
            if (maxRecentOffset < other.maxRecentOffset) return -1;
            if (maxRecentOffset > other.maxRecentOffset) return 1;
            // now check that all offsets are the same over history
            int diffDate = findOffsetOrdering(other, diffDateReturn);
            if (diffDate != 0) return diffDate;
            // choose longer name first!!
            if (id.length() != other.id.length()) {
                if (id.length() < other.id.length()) return 1;
                return -1;
            }
            return id.compareTo(other.id);
        }
        
        public Set getPurportedAliases() {
            return new TreeSet(purportedAliases); // clone for safety
        }
        
        public boolean isPurportedAlias(String zoneID) {
            return purportedAliases.contains(zoneID);
        }
        
        public boolean isRealAlias(Zone z) {
            return purportedAliases.contains(z.id);
        }
        
        public String getPurportedAliasesAsString() {
            Set s = getPurportedAliases();
            if (s.size() == 0) return "";
            return " " + bf.join(s);
        }
        
        public String getRealAliasesAsString() {
            Set s = (Set)idToRealAliases.get(id);
            if (s == null) return "";
            return " *" + bf.join(s);
        }
        
        public String getCity() {
            int pos = id.lastIndexOf(('/'));
            String city = id.substring(pos+1);
            return city.replace('_',' ');
        }

        public String toString() {
            return toString(-1);
        }
        
        /**
         * Where count > 0, returns string that is set up for translation
         */
        public String toString(int count) {
            String city = getCity();
            String hours = formatHours(minRecentOffset)
                + (minRecentOffset != maxRecentOffset 
                    ? "," + formatHours(maxRecentOffset) 
                    : "");
            if (count < 0) {
                return id + getPurportedAliasesAsString() + " (" + hours + ")";
            } 
            // for getting template for translation
            return "\t{\t\"" + id + "\"\t// [" + count + "] " + hours 
                + getRealAliasesAsString() + "\r\n"
                + "\t\t// translate the following!!\r\n"
                + (minRecentOffset != maxRecentOffset
                    ? "\t\t\"" + city + " Standard Time\"\r\n"
                    + "\t\t\"" + city + "-ST\"\r\n"
                    + "\t\t\"" + city + " Daylight Time\"\r\n"
                    + "\t\t\"" + city + "-DT\"\r\n"
                    : "\t\t\"\"\r\n"
                    + "\t\t\"\"\r\n"
                    + "\t\t\"\"\r\n"
                    + "\t\t\"\"\r\n")
                + "\t\t\"" + city + " Time\"\r\n"
                + "\t\t\"" + city + "-T\"\r\n"
                + "\t\t\"" + city + "\"\r\n"
                + "\t}";
        }
    }
}

//#endif
