/*
 * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package build.tools.javazic;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Main class for the javazic time zone data compiler.
 *
 * @since 1.4
 */
public class Main {

    private static boolean verbose = false;
    static boolean outputDoc = false;

    private List<String> ziFiles = new ArrayList<String>();
    private static String zoneNamesFile = null;
    private static String versionName = "unknown";
    private static String outputDir = "zoneinfo";
    private static String mapFile = null;

    /**
     * Parses the specified arguments and sets up the variables.
     * @param argv the arguments
     */
    void processArgs(String[] argv) {
        for (int i = 0; i < argv.length; i++) {
            String arg = argv[i];
            if (arg.startsWith("-h")) {
                usage();
                System.exit(0);
            } else if (arg.equals("-d")) {
                outputDir = argv[++i];
            } else if (arg.equals("-v")) {
                verbose = true;
            } else if (arg.equals("-V")) {
                versionName = argv[++i];
            } else if (arg.equals("-doc")) {
                outputDoc = true;
            } else if (arg.equals("-map")) {
                outputDoc = true;
                mapFile = argv[++i];
            } else if (arg.equals("-f")) {
                zoneNamesFile = argv[++i];
            } else if (arg.equals("-S")) {
                try {
                    Zoneinfo.setYear(Integer.parseInt(argv[++i]));
                } catch (Exception e) {
                    error("invalid year: " + argv[i]);
                    usage();
                    System.exit(1);
                }
            } else {
                boolean isStartYear = arg.equals("-s");
                if (isStartYear || arg.equals("-e")) {
                    try {
                        int year = Integer.parseInt(argv[++i]);
                        if (isStartYear) {
                            Zoneinfo.setStartYear(year);
                        } else {
                            Zoneinfo.setEndYear(year);
                        }
                    } catch (Exception e) {
                        error("invalid year: " + argv[i]);
                        usage();
                        System.exit(1);
                    }
                } else {
                    // the rest of args are zoneinfo source files
                    while (i < argv.length) {
                        ziFiles.add(argv[i++]);
                    }
                }
            }
        }
    }

    /**
     * Parses zoneinfo source files
     */
    int compile() {
        int nFiles = ziFiles.size();
        int status = 0;
        Mappings maps = new Mappings();
        BackEnd backend = BackEnd.getBackEnd();

        for (int i = 0; i < nFiles; i++) {
            Zoneinfo frontend = Zoneinfo.parse(ziFiles.get(i));

            for (String key : frontend.getZones().keySet()) {
                info(key);

                Timezone tz = frontend.phase2(key);
                status |= backend.processZoneinfo(tz);
            }

            maps.add(frontend);
        }

        // special code for dealing with the conflicting name "MET"
        Zone.addMET();

        maps.resolve();

        status |= backend.generateSrc(maps);

        return status;
    }

    public static void main(String[] argv) {
        Main zic = new Main();

        /*
         * Parse args
         */
        zic.processArgs(argv);

        /*
         * Read target zone names
         */
        if (zoneNamesFile != null) {
            Zone.readZoneNames(zoneNamesFile);
        }

        int status = zic.compile();

        System.exit(status);
    }

    void usage() {
        System.err.println("Usage: javazic [options] file...\n"+
                           "         -f namefile  file containing zone names\n"+
                           "                      to be generated (ie, generating subset)\n"+
                           "         -d dir       output directory\n"+
                           "         -v           verbose\n"+
                           "         -V datavers  specifies the tzdata version string\n"+
                           "                      (eg, \"tzdata2000g\")"+
                           "         -S year      output only SimleTimeZone data of that year\n"+
                           "         -s year      start year (default: 1900)\n"+
                           "         -e year      end year (default: 2037)\n"+
                           "         -doc         generates HTML documents\n"+
                           "         -map mapfile generates HTML documents with map information\n"+
                           "         file...      zoneinfo source file(s)");
    }

    /**
     * @return the output directory path name
     */
    static String getOutputDir() {
        return outputDir;
    }

    /**
     * @return the map file's path and name
     */
    static String getMapFile() {
        return mapFile;
    }

    /**
     * Returns the time zone data version string specified by the -V
     * option. If it is not specified, "unknown" is returned.
     * @return the time zone data version string
     */
    static String getVersionName() {
        return versionName;
    }

    /**
     * Prints out the specified fatal error message and calls {@link
     * java.lang.System#exit System.exit(1)}.
     * @param msg the fatal error message
     */
    static void panic(String msg) {
        printMessage("fatal error", msg);
        System.exit(1);
    }

    /**
     * Prints out the specified error message.
     * @param msg the error message
     */
    static void error(String msg) {
        printMessage("error", msg);
    }

    /**
     * Prints out the specified warning message.
     * @param msg the warning message
     */
    static void warning(String msg) {
        printMessage("warning", msg);
    }

    /**
     * Prints out the informative message.
     * @param msg the informative message
     */
    static void info(String msg) {
        if (verbose) {
            printMessage(null, msg);
        }
    }

    private static void printMessage(String type, String msg) {
        if (type != null) {
            type += ": ";
        } else {
            type = "";
        }
        System.err.println("javazic: " + type + msg);
    }
}
