// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
 ***********************************************************************
 * 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.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];
        cutovers[0] = tz.getTime(loyear, 0, 1, 0, 0, 0);
        cutovers[1] = tz.getTime(hiyear, 0, 1, 0, 0, 0);
        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 long getTime(int year, int month, int dayOfMonth, int hour, int minute, int second) {
            long time;
            if (tzobj instanceof com.ibm.icu.util.TimeZone) {
                GregorianCalendar cal = new GregorianCalendar();
                cal.setTimeZone((com.ibm.icu.util.TimeZone)tzobj);
                cal.clear();
                cal.set(year, month, dayOfMonth, hour, minute, second);
                time = cal.getTimeInMillis();
            } else if (tzobj instanceof java.util.TimeZone) {
                java.util.GregorianCalendar cal = new java.util.GregorianCalendar();
                cal.setTimeZone((java.util.TimeZone)tzobj);
                cal.clear();
                cal.set(year, month, dayOfMonth, hour, minute, second);
                time = cal.getTimeInMillis();
            } else {
                throw new IllegalStateException("Unsupported TimeZone implementation");
            }
            return time;
        }
    }

    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);
        dumper.dump(w);
    }
}
