/*
 * Written by Dawid Kurzyniec and released to the public domain, as explained
 * at http://creativecommons.org/licenses/publicdomain
 */

package edu.emory.mathcs.util;

/**
 * To be reengineered.
 *
 * @author Dawid Kurzyniec
 * @version 1.0
 */
public class ArgvUtils {

    private ArgvUtils() {}

    public static String[] shift(String[] args) {
        return shift(args, 1);
    }

    public static String[] shift(String[] args, int n) {
        if (args.length == 0) return args;
        if (args.length <= n) return new String[0];
        String[] newArgs = new String[args.length-n];
        System.arraycopy(args, n, newArgs, 0, newArgs.length);
        return newArgs;
    }

    public static boolean isOption(String arg) {
        return (arg.startsWith("-"));
    }

    /** To be reengineered.
     */
    public static class OptionIterator {
        final String[] args;
        int idx;
        int lookaheadIdx;
        OptionEntry lookahead;
        public OptionIterator(String[] args) {
            this.args = args;
            this.idx = 0;
            this.lookaheadIdx = 0;
            this.lookahead = lookahead();
        }

        public boolean hasNext() {
            return (lookahead != null);
        }

        public OptionEntry next() {
            OptionEntry next = lookahead;
            idx = lookaheadIdx;
            lookahead = lookahead();
            return next;
        }

        public int getOffset() {
            return idx;
        }

        public String[] getRemainingArgs() {
            String[] remaining = new String[args.length-idx];
            System.arraycopy(args, idx, remaining, 0, args.length-idx);
            return remaining;
        }

        private OptionEntry lookahead() {
            if (lookaheadIdx >= args.length || !isOption(args[lookaheadIdx])) {
                return null;
            }
            String option = args[lookaheadIdx++];
            if (option.length() > 0 && option.charAt(0) == '-') {
                option = option.substring(1);
            }
            if (option.length() > 0 && option.charAt(0) == '-') {
                option = option.substring(1);
            }
            String name;
            String val;
            int pos = option.indexOf('=');
            if (pos >= 0) {
                name = option.substring(0, pos);
                val = option.substring(pos+1);
                return new OptionEntry(name, val);
            }

            name = option;
            // we now have the name; try to fetch the value
            if (idx >= args.length || lookaheadIdx >= args.length ||
                isOption(args[lookaheadIdx]))
            {
                return new OptionEntry(name, null);
            }

            return new OptionEntry(name, args[lookaheadIdx++]);
        }
    }

    /** To be reengineered.
     */
    public static class OptionEntry {
        final String name;
        final String value;
        OptionEntry(String name, String value) {
            this.name = name;
            this.value = value;
        }
        public String getName() {
            return name;
        }
        public String getValue() {
            if (value == null) {
                throw new IllegalArgumentException(
                    "Missing value for option \"" + name + "\"");
            }
            return value;
        }
        public String getValue(String defaultVal) {
            return value != null ? value : defaultVal;
        }

        public void ensureNoValue() {
            if (value != null) {
                throw new IllegalArgumentException("Superfluous value for option \"" +
                                                   name + "\"");
            }
        }

        public void unrecognized() {
            throw new IllegalArgumentException("Unrecognized option \"" + name + "\"");
        }

        public String toString() {
            return "option [name: \""+name + "\", val: \"" + value + "\"]";
        }
    }
}
