/*
 * Copyright (c) 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 sun.tools.jstat;

import java.io.*;
import java.net.*;
import java.util.*;
import java.util.regex.*;
import sun.jvmstat.monitor.Monitor;
import sun.jvmstat.monitor.VmIdentifier;

/**
 * Class for processing command line arguments and providing method
 * level access to arguments.
 *
 * @author Brian Doherty
 * @since 1.5
 */
public class Arguments {

    private static final boolean debug = Boolean.getBoolean("jstat.debug");
    private static final boolean showUnsupported =
            Boolean.getBoolean("jstat.showUnsupported");

    private static final String JVMSTAT_USERDIR = ".jvmstat";
    private static final String OPTIONS_FILENAME = "jstat_options";
    private static final String ALL_NAMES = "\\w*";

    private Comparator<Monitor> comparator;
    private int headerRate;
    private boolean help;
    private boolean list;
    private boolean options;
    private boolean constants;
    private boolean constantsOnly;
    private boolean strings;
    private boolean timestamp;
    private boolean snap;
    private boolean verbose;
    private String specialOption;
    private String names;

    private OptionFormat optionFormat;

    private int count = -1;
    private int interval = -1;
    private String vmIdString;

    private VmIdentifier vmId;

    public static void printUsage(PrintStream ps) {
        ps.println("Usage: jstat -help|-options");
        ps.println("       jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]");
        ps.println();
        ps.println("Definitions:");
        ps.println("  <option>      An option reported by the -options option");
        ps.println("  <vmid>        Virtual Machine Identifier. A vmid takes the following form:");
        ps.println("                     <lvmid>[@<hostname>[:<port>]]");
        ps.println("                Where <lvmid> is the local vm identifier for the target");
        ps.println("                Java virtual machine, typically a process id; <hostname> is");
        ps.println("                the name of the host running the target Java virtual machine;");
        ps.println("                and <port> is the port number for the rmiregistry on the");
        ps.println("                target host. See the jvmstat documentation for a more complete");
        ps.println("                description of the Virtual Machine Identifier.");
        ps.println("  <lines>       Number of samples between header lines.");
        ps.println("  <interval>    Sampling interval. The following forms are allowed:");
        ps.println("                    <n>[\"ms\"|\"s\"]");
        ps.println("                Where <n> is an integer and the suffix specifies the units as ");
        ps.println("                milliseconds(\"ms\") or seconds(\"s\"). The default units are \"ms\".");
        ps.println("  <count>       Number of samples to take before terminating.");
        ps.println("  -J<flag>      Pass <flag> directly to the runtime system.");

        // undocumented options:
        //   -list [<vmid>]  - list counter names
        //   -snap <vmid>    - snapshot counter values as name=value pairs
        //   -name <pattern> - output counters matching given pattern
        //   -a              - sort in ascending order (default)
        //   -d              - sort in descending order
        //   -v              - verbose output  (-snap)
        //   -constants      - output constants with -name output
        //   -strings        - output strings with -name output
    }

    private static int toMillis(String s) throws IllegalArgumentException {

        String[] unitStrings = { "ms", "s" }; // ordered from most specific to
                                              // least specific
        String unitString = null;
        String valueString = s;

        for (int i = 0; i < unitStrings.length; i++) {
            int index = s.indexOf(unitStrings[i]);
            if (index > 0) {
                unitString = s.substring(index);
                valueString = s.substring(0, index);
                break;
            }
        }

        try {
            int value = Integer.parseInt(valueString);

            if (unitString == null || unitString.compareTo("ms") == 0) {
                return value;
            } else if (unitString.compareTo("s") == 0) {
                return value * 1000;
            } else {
                throw new IllegalArgumentException(
                        "Unknow time unit: " + unitString);
            }
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException(
                    "Could not convert interval: " + s);
        }
    }

    public Arguments(String[] args) throws IllegalArgumentException {
        int argc = 0;

        if (args.length < 1) {
            throw new IllegalArgumentException("invalid argument count");
        }

        if ((args[0].compareTo("-?") == 0)
                || (args[0].compareTo("-help") == 0)) {
            help = true;
            return;
        } else if (args[0].compareTo("-options") == 0) {
            options = true;
            return;
        } else if (args[0].compareTo("-list") == 0) {
            list = true;
            if (args.length > 2) {
              throw new IllegalArgumentException("invalid argument count");
            }
            // list can take one arg - a vmid - fall through for arg processing
            argc++;
        }

        for ( ; (argc < args.length) && (args[argc].startsWith("-")); argc++) {
            String arg = args[argc];

            if (arg.compareTo("-a") == 0) {
                comparator = new AscendingMonitorComparator();
            } else if (arg.compareTo("-d") == 0) {
                comparator =  new DescendingMonitorComparator();
            } else if (arg.compareTo("-t") == 0) {
                timestamp = true;
            } else if (arg.compareTo("-v") == 0) {
                verbose = true;
            } else if ((arg.compareTo("-constants") == 0)
                       || (arg.compareTo("-c") == 0)) {
                constants = true;
            } else if ((arg.compareTo("-strings") == 0)
                       || (arg.compareTo("-s") == 0)) {
                strings = true;
            } else if (arg.startsWith("-h")) {
                String value;
                if (arg.compareTo("-h") != 0) {
                    value = arg.substring(2);
                } else {
                    argc++;
                    if (argc >= args.length) {
                        throw new IllegalArgumentException(
                                "-h requires an integer argument");
                    }
                    value = args[argc];
                }
                try {
                    headerRate = Integer.parseInt(value);
                } catch (NumberFormatException e) {
                    headerRate = -1;
                }
                if (headerRate < 0) {
                    throw new IllegalArgumentException(
                            "illegal -h argument: " + value);
                }
            } else if (arg.startsWith("-name")) {
                if (arg.startsWith("-name=")) {
                    names = arg.substring(7);
                } else {
                    argc++;
                    if (argc >= args.length) {
                        throw new IllegalArgumentException(
                                "option argument expected");
                    }
                    names = args[argc];
                }
            } else {
                /*
                 * there are scenarios here: special jstat_options file option
                 * or the rare case of a negative lvmid. The negative lvmid
                 * can occur in some operating environments (such as Windows
                 * 95/98/ME), so we provide for this case here by checking if
                 * the argument has any numerical characters. This assumes that
                 * there are no special jstat_options that contain numerical
                 * characters in their name.
                 */

                // extract the lvmid part of possible lvmid@host.domain:port
                String lvmidStr = null;
                int at_index = args[argc].indexOf('@');
                if (at_index < 0) {
                    lvmidStr = args[argc];
                } else {
                    lvmidStr = args[argc].substring(0, at_index);
                }

                // try to parse the lvmid part as an integer
                try {
                    int vmid = Integer.parseInt(lvmidStr);
                    // it parsed, assume a negative lvmid and continue
                    break;
                } catch (NumberFormatException nfe) {
                    // it didn't parse. check for the -snap or jstat_options
                    // file options.
                    if ((argc == 0) && (args[argc].compareTo("-snap") == 0)) {
                        snap = true;
                    } else if (argc == 0) {
                        specialOption = args[argc].substring(1);
                    } else {
                        throw new IllegalArgumentException(
                                "illegal argument: " + args[argc]);
                    }
                }
            }
        }

        // prevent 'jstat <pid>' from being accepted as a valid argument
        if (!(specialOption != null || list || snap || names != null)) {
            throw new IllegalArgumentException("-<option> required");
        }

        switch (args.length - argc) {
        case 3:
            if (snap) {
                throw new IllegalArgumentException("invalid argument count");
            }
            try {
                count = Integer.parseInt(args[args.length-1]);
            } catch (NumberFormatException e) {
                throw new IllegalArgumentException("illegal count value: "
                                                   + args[args.length-1]);
            }
            interval = toMillis(args[args.length-2]);
            vmIdString = args[args.length-3];
            break;
        case 2:
            if (snap) {
                throw new IllegalArgumentException("invalid argument count");
            }
            interval = toMillis(args[args.length-1]);
            vmIdString = args[args.length-2];
            break;
        case 1:
            vmIdString = args[args.length-1];
            break;
        case 0:
            if (!list) {
                throw new IllegalArgumentException("invalid argument count");
            }
            break;
        default:
            throw new IllegalArgumentException("invalid argument count");
        }

        // set count and interval to their default values if not set above.
        if (count == -1 && interval == -1) {
            // default is for a single sample
            count = 1;
            interval = 0;
        }

        // validate arguments
        if (comparator == null) {
            comparator = new AscendingMonitorComparator();
        }

        // allow ',' characters to separate names, convert to '|' chars
        names = (names == null) ? ALL_NAMES : names.replace(',', '|');

        // verify that the given pattern parses without errors
        try {
            Pattern pattern = Pattern.compile(names);
        } catch (PatternSyntaxException e) {
            throw new IllegalArgumentException("Bad name pattern: "
                                               + e.getMessage());
        }

        // verify that the special option is valid and get it's formatter
        if (specialOption != null) {
            OptionFinder finder = new OptionFinder(optionsSources());
            optionFormat = finder.getOptionFormat(specialOption, timestamp);
            if (optionFormat == null) {
                throw new IllegalArgumentException("Unknown option: -"
                                                   + specialOption);
            }
        }

        // verify that the vm identifier is valied
        try {
            vmId = new VmIdentifier(vmIdString);
        } catch (URISyntaxException e) {
            IllegalArgumentException iae = new IllegalArgumentException(
                    "Malformed VM Identifier: " + vmIdString);
            iae.initCause(e);
            throw iae;
        }
    }

    public Comparator<Monitor> comparator() {
        return comparator;
    }

    public boolean isHelp() {
        return help;
    }

    public boolean isList() {
        return list;
    }

    public boolean isSnap() {
        return snap;
    }

    public boolean isOptions() {
        return options;
    }

    public boolean isVerbose() {
        return verbose;
    }

    public boolean printConstants() {
        return constants;
    }

    public boolean isConstantsOnly() {
        return constantsOnly;
    }

    public boolean printStrings() {
        return strings;
    }

    public boolean showUnsupported() {
        return showUnsupported;
    }

    public int headerRate() {
        return headerRate;
    }

    public String counterNames() {
        return names;
    }

    public VmIdentifier vmId() {
        return vmId;
    }

    public String vmIdString() {
        return vmIdString;
    }

    public int sampleInterval() {
        return interval;
    }

    public int sampleCount() {
        return count;
    }

    public boolean isTimestamp() {
        return timestamp;
    }

    public boolean isSpecialOption() {
        return specialOption != null;
    }

    public String specialOption() {
        return specialOption;
    }

    public OptionFormat optionFormat() {
        return optionFormat;
    }

    public URL[] optionsSources() {
        URL[] sources = new URL[2];
        int i = 0;

        String filename = OPTIONS_FILENAME;

        try {
            String userHome = System.getProperty("user.home");
            String userDir = userHome + "/" + JVMSTAT_USERDIR;
            File home = new File(userDir + "/" + filename);
            sources[i++] = home.toURL();
        } catch (Exception e) {
            if (debug) {
                System.err.println(e.getMessage());
                e.printStackTrace();
            }
            throw new IllegalArgumentException("Internal Error: Bad URL: "
                                               + e.getMessage());
        }
        sources[i] = this.getClass().getResource("resources/" + filename);
        assert sources[i] != null;
        return sources;
    }
}
