/*
 * Copyright (c) 2010, 2013, 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 jdk.nashorn.internal.runtime.options;

import java.util.Locale;
import java.util.TimeZone;
import jdk.nashorn.internal.runtime.QuotedStringTokenizer;

/**
 * This describes the valid input for an option, as read from the resource
 * bundle file. Metainfo such as parameters and description is here as well
 * for context sensitive help generation.
 */
public final class OptionTemplate implements Comparable<OptionTemplate> {
    /** Resource, e.g. "nashorn" for this option */
    private final String resource;

    /** Key in the resource bundle */
    private final String key;

    /** Is this option a help option? */
    private final boolean isHelp;

    /** Is this option a extended help option? */
    private final boolean isXHelp;

    /** Name - for example --dump-on-error (usually prefixed with --) */
    private String name;

    /** Short name - for example -doe (usually prefixed with -) */
    private String shortName;

    /** Params - a parameter template string */
    private String params;

    /** Type - e.g. "boolean". */
    private String type;

    /** Does this option have a default value? */
    private String defaultValue;

    /** Does this option activate another option when set? */
    private String dependency;

    /** Does this option conflict with another? */
    private String conflict;

    /** Is this a documented option that should show up in help? */
    private boolean isUndocumented;

    /** A longer description of what this option does */
    private String description;

    /** is the option value specified as next argument? */
    private boolean valueNextArg;

    OptionTemplate(final String resource, final String key, final String value, final boolean isHelp, final boolean isXHelp) {
        this.resource = resource;
        this.key = key;
        this.isHelp = isHelp;
        this.isXHelp = isXHelp;
        parse(value);
    }

    /**
     * Is this the special help option, used to generate help for
     * all the others
     *
     * @return true if this is the help option
     */
    public boolean isHelp() {
        return this.isHelp;
    }

    /**
     * Is this the special extended help option, used to generate extended help for
     * all the others
     *
     * @return true if this is the extended help option
     */
    public boolean isXHelp() {
        return this.isXHelp;
    }

    /**
     * Get the resource name used to prefix this option set, e.g. "nashorn"
     *
     * @return the name of the resource
     */
    public String getResource() {
        return this.resource;
    }

    /**
     * Get the type of this option
     *
     * @return the type of the option
     */
    public String getType() {
        return this.type;
    }

    /**
     * Get the key of this option
     *
     * @return the key
     */
    public String getKey() {
        return this.key;
    }

    /**
     * Get the default value for this option
     *
     * @return the default value as a string
     */
    public String getDefaultValue() {
        switch (getType()) {
        case "boolean":
            if (this.defaultValue == null) {
                this.defaultValue = "false";
            }
            break;
        case "integer":
            if (this.defaultValue == null) {
                this.defaultValue = "0";
            }
            break;
        case "timezone":
            this.defaultValue = TimeZone.getDefault().getID();
            break;
        case "locale":
            this.defaultValue = Locale.getDefault().toLanguageTag();
            break;
        default:
            break;
        }
        return this.defaultValue;
    }

    /**
     * Does this option automatically enable another option, i.e. a dependency.
     * @return the dependency or null if none exists
     */
    public String getDependency() {
        return this.dependency;
    }

    /**
     * Is this option in conflict with another option so that both can't be enabled
     * at the same time
     *
     * @return the conflicting option or null if none exists
     */
    public String getConflict() {
        return this.conflict;
    }

    /**
     * Is this option undocumented, i.e. should not show up in the standard help output
     *
     * @return true if option is undocumented
     */
    public boolean isUndocumented() {
        return this.isUndocumented;
    }

    /**
     * Get the short version of this option name if one exists, e.g. "-co" for "--compile-only"
     *
     * @return the short name
     */
    public String getShortName() {
        return this.shortName;
    }

    /**
     * Get the name of this option, e.g. "--compile-only". A name always exists
     *
     * @return the name of the option
     */
    public String getName() {
        return this.name;
    }

    /**
     * Get the description of this option.
     *
     * @return the description
     */
    public String getDescription() {
        return this.description;
    }

    /**
     * Is value of this option passed as next argument?
     * @return boolean
     */
    public boolean isValueNextArg() {
        return valueNextArg;
    }

    private static String strip(final String value, final char start, final char end) {
        final int len = value.length();
        if (len > 1 && value.charAt(0) == start && value.charAt(len - 1) == end) {
            return value.substring(1, len - 1);
        }
        return null;
    }

    private void parse(final String origValue) {
        String value = origValue.trim();

        try {
            value = OptionTemplate.strip(value, '{', '}');
            final QuotedStringTokenizer keyValuePairs = new QuotedStringTokenizer(value, ",");

            while (keyValuePairs.hasMoreTokens()) {
                final String                keyValue = keyValuePairs.nextToken();
                final QuotedStringTokenizer st       = new QuotedStringTokenizer(keyValue, "=");
                final String                keyToken = st.nextToken();
                final String                arg      = st.nextToken();

                switch (keyToken) {
                case "is_undocumented":
                    this.isUndocumented = Boolean.parseBoolean(arg);
                    break;
                case "name":
                    if (!arg.startsWith("-")) {
                        throw new IllegalArgumentException(arg);
                    }
                    this.name = arg;
                    break;
                case "short_name":
                    if (!arg.startsWith("-")) {
                        throw new IllegalArgumentException(arg);
                    }
                    this.shortName = arg;
                    break;
                case "desc":
                    this.description = arg;
                    break;
                case "params":
                    this.params = arg;
                    break;
                case "type":
                    this.type = arg.toLowerCase(Locale.ENGLISH);
                    break;
                case "default":
                    this.defaultValue = arg;
                    break;
                case "dependency":
                    this.dependency = arg;
                    break;
                case "conflict":
                    this.conflict = arg;
                    break;
                case "value_next_arg":
                    this.valueNextArg = Boolean.parseBoolean(arg);
                    break;
                default:
                    throw new IllegalArgumentException(keyToken);
                }
            }

            // default to boolean if no type is given
            if (this.type == null) {
                this.type = "boolean";
            }

            if (this.params == null && "boolean".equals(this.type)) {
                this.params = "[true|false]";
            }

        } catch (final Exception e) {
            throw new IllegalArgumentException(origValue);
        }

        if (name == null && shortName == null) {
            throw new IllegalArgumentException(origValue);
        }
    }

    boolean nameMatches(final String aName) {
        return aName.equals(this.shortName) || aName.equals(this.name);
    }

    private static final int LINE_BREAK = 64;

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();

        sb.append('\t');

        if (shortName != null) {
            sb.append(shortName);
            if (name != null) {
                sb.append(", ");
            }
        }

        if (name != null) {
            sb.append(name);
        }

        if (description != null) {
            final int indent = sb.length();
            sb.append(' ');
            sb.append('(');
            int pos = 0;
            for (final char c : description.toCharArray()) {
                sb.append(c);
                pos++;
                if (pos >= LINE_BREAK && Character.isWhitespace(c)) {
                    pos = 0;
                    sb.append("\n\t");
                    for (int i = 0; i < indent; i++) {
                        sb.append(' ');
                    }
                }
            }
            sb.append(')');
        }

        if (params != null) {
            sb.append('\n');
            sb.append('\t');
            sb.append('\t');
            sb.append(Options.getMsg("nashorn.options.param")).append(": ");
            sb.append(params);
            sb.append("   ");
            final Object def = this.getDefaultValue();
            if (def != null) {
                sb.append(Options.getMsg("nashorn.options.default")).append(": ");
                sb.append(this.getDefaultValue());
            }
        }


        return sb.toString();
    }

    @Override
    public int compareTo(final OptionTemplate o) {
        return this.getKey().compareTo(o.getKey());
    }
}
