/*
 ***********************************************************************
 * Copyright (C) 2007, International Business Machines                 *
 * Corporation and others. All Rights Reserved.                        *
 ***********************************************************************
 *
 */

package com.ibm.icu.dev.tool.timezone;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.TreeSet;

import com.ibm.icu.impl.JDKTimeZone;
import com.ibm.icu.text.DecimalFormat;
import com.ibm.icu.text.DecimalFormatSymbols;
import com.ibm.icu.text.SimpleDateFormat;
import com.ibm.icu.util.GregorianCalendar;
import com.ibm.icu.util.SimpleTimeZone;
import com.ibm.icu.util.ULocale;

/**
 * TimeZone transition dump tool.
 */
public class ICUZDump {
    private static final String DEFAULT_LINE_SEP;

    static {
        String sep = System.getProperty("line.separator");
        DEFAULT_LINE_SEP = (sep == null) ? "\n" : sep;
    }

    private TimeZoneImpl tz = null;

    private int loyear = 1900;
    private int hiyear = 2050;
    private long tick = 1000;
    private DumpFormatter formatter;
    private String linesep = DEFAULT_LINE_SEP;

    public ICUZDump() {
    }
    
    public void setLowYear(int loyear) {
        this.loyear = loyear;
    }
    
    public void setHighYear(int hiyear) {
        this.hiyear = hiyear;
    }

    public void setTick(int tick) {
        if (tick <= 0) {
            throw new IllegalArgumentException("tick must be positive");
        }
        this.tick = tick;
    }
    
    public void setTimeZone(Object tzimpl) {
        this.tz = new TimeZoneImpl(tzimpl);
    }

    public void setDumpFormatter(DumpFormatter formatter) {
        this.formatter = formatter;
    }
    
    public void setLineSeparator(String sep) {
        this.linesep = sep;
    }
    
    public void dump(Writer w) throws IOException {
        if (tz == null) {
            throw new IllegalStateException("timezone is not initialized");
        }

        if (formatter == null) {
            formatter = new DumpFormatter();
        }
        
        final long SEARCH_INCREMENT = 12 * 60 * 60 * 1000; // half day
        long cutovers[] = getCutOverTimes();
        long t = cutovers[0];
        int offset = tz.getOffset(t);
        boolean inDst = tz.inDaylightTime(t);
        while (t < cutovers[1]) {
            long newt = t + SEARCH_INCREMENT;
            int newOffset = tz.getOffset(newt);
            boolean newInDst = tz.inDaylightTime(newt);
            if (offset != newOffset || inDst != newInDst) {
                // find the boundary
                long lot = t;
                long hit = newt;
                while (true) {
                    long diff = hit - lot;
                    if (diff <= tick) {
                        break;
                    }
                    long medt = lot + ((diff / 2) / tick) * tick;
                    int medOffset = tz.getOffset(medt);
                    boolean medInDst = tz.inDaylightTime(medt);
                    if (medOffset != offset || medInDst != inDst) {
                        hit = medt;
                    } else {
                        lot = medt;
                    }
                }
                w.write(formatter.format(lot, offset, tz.inDaylightTime(lot)));
                w.write(" > ");
                w.write(formatter.format(hit, newOffset, tz.inDaylightTime(hit)));
                w.write(linesep);
                offset = newOffset;
                inDst = newInDst;
            }
            t = newt;
        }

    }
    
    private long[] getCutOverTimes() {
        long[] cutovers = new long[2];
        GregorianCalendar cal = tz.getCalendar();
        cal.clear();
        cal.set(loyear, 0, 1, 0, 0, 0);
        cutovers[0] = cal.getTimeInMillis();

        cal.clear();
        cal.set(hiyear, 0, 1, 0, 0, 0);
        cutovers[1] = cal.getTimeInMillis();
        return cutovers;
    }

    private class TimeZoneImpl {
        private Object tzobj;
        
        public TimeZoneImpl(Object tzobj) {
            this.tzobj = tzobj;
        }

        public int getOffset(long time) {
            try {
                Method method = tzobj.getClass().getMethod("getOffset", new Class[] {long.class});
                Object result = method.invoke(tzobj, new Object[] {new Long(time)});
                return ((Integer)result).intValue();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return 0;
        }

        public boolean inDaylightTime(long time) {
            try {
                Method method = tzobj.getClass().getMethod("inDaylightTime", new Class[] {Date.class});
                Object result = method.invoke(tzobj, new Object[] {new Date(time)});
                return ((Boolean)result).booleanValue();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return false;
        }

        public GregorianCalendar getCalendar() {
            GregorianCalendar cal = new GregorianCalendar();
            com.ibm.icu.util.TimeZone icutz = null;
            if (tzobj instanceof com.ibm.icu.util.TimeZone) {
                icutz = (com.ibm.icu.util.TimeZone)tzobj;
            } else if (tzobj instanceof java.util.TimeZone) {
                icutz = new JDKTimeZone((java.util.TimeZone)tzobj);
            } else {
                throw new IllegalStateException("Unsupported TimeZone implementation");
            }
            cal.setTimeZone(icutz);
            return cal;
        }
    }

    public class DumpFormatter {
        private SimpleTimeZone stz = new SimpleTimeZone(0, "");
        private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd EEE HH:mm:ss", ULocale.US);
        private DecimalFormat decf;

        public DumpFormatter() {
            DecimalFormatSymbols decfs = new DecimalFormatSymbols(ULocale.US);
            decf = new DecimalFormat("00", decfs);
        }

        public String format(long time, int offset, boolean isDst) {
            StringBuffer buf = new StringBuffer();
            stz.setRawOffset(offset);
            sdf.setTimeZone(stz);
            buf.append(sdf.format(new Date(time)));
            if (offset < 0) {
                buf.append("-");
                offset = -offset;
            } else {
                buf.append("+");
            }

            int hour, min, sec;

            offset /= 1000;
            sec = offset % 60;
            offset = (offset - sec) / 60;
            min = offset % 60;
            hour = offset / 60;

            buf.append(decf.format(hour));
            buf.append(decf.format(min));
            buf.append(decf.format(sec));

            buf.append("[DST=");
            buf.append(isDst ? "1" : "0");
            buf.append("]");
            return buf.toString();
        }
    }

    /*
     * Usage:
     * 
     * java -cp icu4j.jar com.ibm.icu.dev.tool.timezone [-j] [-a] [-c[<low_year>,]<high_year>] [-d<dir>] [-l<sep>] [<zone_name> [<zone_name>]]
     * 
     * Options:
     *      -j      : Use JDK TimeZone.  By default, ICU TimeZone is used.
     *      -a      : Dump all available zones.
     *      -c[<low_year>,]<high_year>
     *              : When specified, dump transitions starting <low_year> (inclusive) up to
     *                <high_year> (exclusive).  The default values are 1902(low) and 2038(high).
     *      -d<dir> : When specified, write transitions in a file under the directory for each zone.
     *      -l<sep> : New line code type CR/LF/CRLF.
     */
    public static void main(String[] args) {
        boolean jdk = false;
        int low = 1902;
        int high = 2038;
        List idlist = new ArrayList();
        boolean all = false;
        String dir = null;
        String newLineMode = null;
        for (int i = 0; i < args.length; i++) {
            if (args[i].equals("-j")) {
                jdk = true;
            } else if (args[i].startsWith("-c")) {
                String val = args[i].substring(2);
                String[] years = val.split(",");
                if (years.length == 1) {
                    high = Integer.parseInt(years[0]);
                } else if (years.length == 2) {
                    low = Integer.parseInt(years[0]);
                    high = Integer.parseInt(years[1]);
                }
            } else if (args[i].equals("-a")) {
                all = true;
            } else if (args[i].startsWith("-d")) {
                dir = args[i].substring(2);
            } else if (args[i].startsWith("-l")) {
                newLineMode = args[i].substring(2);
            } else if (!args[i].startsWith("-")){
                idlist.add(args[i].trim());
            }
        }

        String lineSep = System.getProperty("line.separator");
        if (newLineMode != null && newLineMode.length() > 0) {
            if (newLineMode.equalsIgnoreCase("CR")) {
                lineSep = "\r";
            } else if (newLineMode.equalsIgnoreCase("LF")) {
                lineSep = "\n";
            } else if (newLineMode.equalsIgnoreCase("CRLF")) {
                lineSep = "\r\n";            
            }
        }
        
        String[] tzids = null;

        if (all) {
            if (jdk) {
                tzids = java.util.TimeZone.getAvailableIDs();
            } else {
                tzids = com.ibm.icu.util.TimeZone.getAvailableIDs();
            }

            // sort tzids
            TreeSet set = new TreeSet();
            for (int i = 0; i < tzids.length; i++) {
                set.add(tzids[i]);
            }
            Iterator it = set.iterator();
            int i = 0;
            while (it.hasNext()) {
                tzids[i++] = (String)it.next();
            }
        } else {
            int len = idlist.size();
            if (len == 0) {
                tzids = new String[1];
                tzids[0] = java.util.TimeZone.getDefault().getID();
            } else {
                tzids = new String[idlist.size()];
                idlist.toArray(tzids);
            }            
        }

        File dirfile = null;
        if (dir == null || dir.length() == 0) {
            PrintWriter pw = new PrintWriter(System.out);
            try {
                for (int i = 0; i < tzids.length; i++) {
                    if (i != 0) {
                        pw.println();
                    }
                    pw.write("ZONE: ");
                    pw.write(tzids[i]);
                    pw.println();
                    dumpZone(pw, lineSep, tzids[i], low, high, jdk);
                }
                pw.flush();
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        } else {
            dirfile = new File(dir);
            dirfile.mkdirs();

            try {
                for (int i = 0; i < tzids.length; i++) {
                    FileOutputStream fos = new FileOutputStream(new File(dirfile, tzids[i].replace('/', '-')));
                    Writer w = new BufferedWriter(new OutputStreamWriter(fos));
                    dumpZone(w, lineSep, tzids[i], low, high, jdk);
                    w.close();
                }
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }
    }

    private static void dumpZone(Writer w, String lineSep, String tzid, int low, int high, boolean isJdk) throws IOException {
        ICUZDump dumper = new ICUZDump();
        Object tzimpl;
        if (isJdk) {
            tzimpl = java.util.TimeZone.getTimeZone(tzid);
        } else {
            tzimpl = com.ibm.icu.util.TimeZone.getTimeZone(tzid);
        }
        dumper.setTimeZone(tzimpl);
        dumper.setLowYear(low);
        dumper.setHighYear(high);
        dumper.setLineSeparator(lineSep);
        try {
            dumper.dump(w);
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }
}
