/*
 * Copyright 1998-2003 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package com.sun.tools.jdi;

import com.sun.tools.jdi.*;
import com.sun.jdi.*;
import com.sun.jdi.connect.*;
import com.sun.jdi.InternalException;
import java.util.Collections;
import java.util.Collection;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ResourceBundle;
import java.io.Serializable;

abstract class ConnectorImpl implements Connector {
    Map<String,Argument> defaultArguments = new java.util.LinkedHashMap<String,Argument>();

    // Used by BooleanArgument
    static String trueString = null;
    static String falseString;

    public Map<String,Argument> defaultArguments() {
        Map<String,Argument> defaults = new java.util.LinkedHashMap<String,Argument>();
        Collection values = defaultArguments.values();

        Iterator iter = values.iterator();
        while (iter.hasNext()) {
            ArgumentImpl argument = (ArgumentImpl)iter.next();
            defaults.put(argument.name(), (Argument)argument.clone());
        }
        return defaults;
    }

    void addStringArgument(String name, String label, String description,
                           String defaultValue, boolean mustSpecify) {
        defaultArguments.put(name,
                             new StringArgumentImpl(name, label,
                                                    description,
                                                    defaultValue,
                                                    mustSpecify));
    }

    void addBooleanArgument(String name, String label, String description,
                            boolean defaultValue, boolean mustSpecify) {
        defaultArguments.put(name,
                             new BooleanArgumentImpl(name, label,
                                                     description,
                                                     defaultValue,
                                                     mustSpecify));
    }

    void addIntegerArgument(String name, String label, String description,
                            String defaultValue, boolean mustSpecify,
                            int min, int max) {
        defaultArguments.put(name,
                             new IntegerArgumentImpl(name, label,
                                                     description,
                                                     defaultValue,
                                                     mustSpecify,
                                                     min, max));
    }

    void addSelectedArgument(String name, String label, String description,
                             String defaultValue, boolean mustSpecify,
                             List<String> list) {
        defaultArguments.put(name,
                             new SelectedArgumentImpl(name, label,
                                                      description,
                                                      defaultValue,
                                                      mustSpecify, list));
    }

    ArgumentImpl argument(String name, Map arguments)
                throws IllegalConnectorArgumentsException {

        ArgumentImpl argument = (ArgumentImpl)arguments.get(name);
        if (argument == null) {
            throw new IllegalConnectorArgumentsException(
                         "Argument missing", name);
        }
        String value = argument.value();
        if (value == null || value.length() == 0) {
            if (argument.mustSpecify()) {
            throw new IllegalConnectorArgumentsException(
                         "Argument unspecified", name);
            }
        } else if(!argument.isValid(value)) {
            throw new IllegalConnectorArgumentsException(
                         "Argument invalid", name);
        }

        return argument;
    }


    private ResourceBundle messages = null;

    String getString(String key) {
        if (messages == null) {
            messages = ResourceBundle.getBundle("com.sun.tools.jdi.resources.jdi");
        }
        return messages.getString(key);
    }

    public String toString() {
        String string = name() + " (defaults: ";
        Iterator iter = defaultArguments().values().iterator();
        boolean first = true;
        while (iter.hasNext()) {
            ArgumentImpl argument = (ArgumentImpl)iter.next();
            if (!first) {
                string += ", ";
            }
            string += argument.toString();
            first = false;
        }
        string += ")";
        return string;
    }

    abstract class ArgumentImpl implements Connector.Argument, Cloneable, Serializable {
        private String name;
        private String label;
        private String description;
        private String value;
        private boolean mustSpecify;

        ArgumentImpl(String name, String label, String description,
                     String value,
                     boolean mustSpecify) {
            this.name = name;
            this.label = label;
            this.description = description;
            this.value = value;
            this.mustSpecify = mustSpecify;
        }

        public abstract boolean isValid(String value);

        public String name() {
            return name;
        }

        public String label() {
            return label;
        }

        public String description() {
            return description;
        }

        public String value() {
            return value;
        }

        public void setValue(String value) {
            if (value == null) {
                throw new NullPointerException("Can't set null value");
            }
            this.value = value;
        }

        public boolean mustSpecify() {
            return mustSpecify;
        }

        public boolean equals(Object obj) {
            if ((obj != null) && (obj instanceof Connector.Argument)) {
                Connector.Argument other = (Connector.Argument)obj;
                return (name().equals(other.name())) &&
                       (description().equals(other.description())) &&
                       (mustSpecify() == other.mustSpecify()) &&
                       (value().equals(other.value()));
            } else {
                return false;
            }
        }

        public int hashCode() {
            return description().hashCode();
        }

        public Object clone() {
            try {
                return super.clone();
            } catch (CloneNotSupportedException e) {
                // Object should always support clone
                throw new InternalException();
            }
        }

        public String toString() {
            return name() + "=" + value();
        }
    }

    class BooleanArgumentImpl extends ConnectorImpl.ArgumentImpl
                              implements Connector.BooleanArgument {

        BooleanArgumentImpl(String name, String label, String description,
                            boolean value,
                            boolean mustSpecify) {
            super(name, label, description, null, mustSpecify);
            if(trueString == null) {
                trueString = getString("true");
                falseString = getString("false");
            }
            setValue(value);
        }

        /**
         * Sets the value of the argument.
         */
        public void setValue(boolean value) {
            setValue(stringValueOf(value));
        }

        /**
         * Performs basic sanity check of argument.
         * @return <code>true</code> if value is a string
         * representation of a boolean value.
         * @see #stringValueOf(boolean)
         */
        public boolean isValid(String value) {
            return value.equals(trueString) || value.equals(falseString);
        }

        /**
         * Return the string representation of the <code>value</code>
         * parameter.
         * Does not set or examine the value or the argument.
         * @return the localized String representation of the
         * boolean value.
         */
        public String stringValueOf(boolean value) {
            return value? trueString : falseString;
        }

        /**
         * Return the value of the argument as a boolean.  Since
         * the argument may not have been set or may have an invalid
         * value {@link #isValid(String)} should be called on
         * {@link #value()} to check its validity.  If it is invalid
         * the boolean returned by this method is undefined.
         * @return the value of the argument as a boolean.
         */
        public boolean booleanValue() {
            return value().equals(trueString);
        }
    }

    class IntegerArgumentImpl extends ConnectorImpl.ArgumentImpl
                              implements Connector.IntegerArgument {

        private final int min;
        private final int max;

        IntegerArgumentImpl(String name, String label, String description,
                            String value,
                            boolean mustSpecify, int min, int max) {
            super(name, label, description, value, mustSpecify);
            this.min = min;
            this.max = max;
        }

        /**
         * Sets the value of the argument.
         * The value should be checked with {@link #isValid(int)}
         * before setting it; invalid values will throw an exception
         * when the connection is established - for example,
         * on {@link LaunchingConnector#launch}
         */
        public void setValue(int value) {
            setValue(stringValueOf(value));
        }

        /**
         * Performs basic sanity check of argument.
         * @return <code>true</code> if value represents an int that is
         * <code>{@link #min()} &lt;= value &lt;= {@link #max()}</code>
         */
        public boolean isValid(String value) {
            if (value == null) {
                return false;
            }
            try {
                return isValid(Integer.decode(value).intValue());
            } catch(NumberFormatException exc) {
                return false;
            }
        }

        /**
         * Performs basic sanity check of argument.
         * @return <code>true</code> if
         * <code>{@link #min()} &lt;= value  &lt;= {@link #max()}</code>
         */
        public boolean isValid(int value) {
            return min <= value && value <= max;
        }

        /**
         * Return the string representation of the <code>value</code>
         * parameter.
         * Does not set or examine the value or the argument.
         * @return the String representation of the
         * int value.
         */
        public String stringValueOf(int value) {
            // *** Should this be internationalized????
            // *** Even Brian Beck was unsure if an Arabic programmer
            // *** would expect port numbers in Arabic numerals,
            // *** so punt for now.
            return ""+value;
        }

        /**
         * Return the value of the argument as a int.  Since
         * the argument may not have been set or may have an invalid
         * value {@link #isValid(String)} should be called on
         * {@link #value()} to check its validity.  If it is invalid
         * the int returned by this method is undefined.
         * @return the value of the argument as a int.
         */
        public int intValue() {
            if (value() == null) {
                return 0;
            }
            try {
                return Integer.decode(value()).intValue();
            } catch(NumberFormatException exc) {
                return 0;
            }
        }

        /**
         * The upper bound for the value.
         * @return the maximum allowed value for this argument.
         */
        public int max() {
            return max;
        }

        /**
         * The lower bound for the value.
         * @return the minimum allowed value for this argument.
         */
        public int min() {
            return min;
        }
    }

    class StringArgumentImpl extends ConnectorImpl.ArgumentImpl
                              implements Connector.StringArgument {

        StringArgumentImpl(String name, String label, String description,
                           String value,
                           boolean mustSpecify) {
            super(name, label, description, value, mustSpecify);
        }

        /**
         * Performs basic sanity check of argument.
         * @return <code>true</code> always
         */
        public boolean isValid(String value) {
            return true;
        }
    }

    class SelectedArgumentImpl extends ConnectorImpl.ArgumentImpl
                              implements Connector.SelectedArgument {

        private final List<String> choices;

        SelectedArgumentImpl(String name, String label, String description,
                             String value,
                             boolean mustSpecify, List<String> choices) {
            super(name, label, description, value, mustSpecify);
            this.choices = Collections.unmodifiableList(new ArrayList<String>(choices));
        }

        /**
         * Return the possible values for the argument
         * @return {@link List} of {@link String}
         */
        public List<String> choices() {
            return choices;
        }

        /**
         * Performs basic sanity check of argument.
         * @return <code>true</code> if value is one of {@link #choices()}.
         */
        public boolean isValid(String value) {
            return choices.contains(value);
        }
    }
}
