/*
 *
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package org.apache.royale.formatter.config;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.apache.royale.compiler.internal.config.annotations.DefaultArgumentValue;
import com.google.common.base.Joiner;
import com.google.common.base.MoreObjects;

/**
 * Meta information for each configuration options. It is created by
 * {@link ConfigurationBuffer#loadCache} from either annotations or
 * {@code public static ConfigurationInfo getFooInfo();} methods in
 * {@link Configuration} class.
 */
public class ConfigurationInfo
{
    public static final int NOT_SET = -2;
    public static final int INFINITE_ARGS = -1;

    /**
     * This ctor is used when everything can be introspected off the setter
     * method, or else when the names/types are provided by method overrides
     * rather than ctor arguments
     */
    public ConfigurationInfo()
    {
        this.argcount = NOT_SET;
        this.argnames = null;
    }

    /**
     * Simple ctor for restricting the number of arguments.
     * 
     * @param argcount number of args, -1 for an infinite list
     */
    public ConfigurationInfo(int argcount)
    {
        this.argcount = argcount;
        this.argnames = null;
    }

    /**
     * Simple ctor for naming the arguments.
     * 
     * @param argnames list of argnames, argcount will default to # of elements
     */
    public ConfigurationInfo(String argnames[])
    {
        this.argcount = argnames.length;
        this.argnames = argnames;
    }

    /**
     * Use this ctor when you want to set a single list of some number of
     * identically named args
     * 
     * @param argcount number of arguments (-1 for infinite)
     * @param argname name of each argument
     */
    public ConfigurationInfo(int argcount, String argname)
    {
        this.argcount = argcount;
        this.argnames = new String[] {argname};
    }

    /**
     * More unusual ctor, this would let you have the first few args named one
     * thing, the rest named something else. It is far more likely that you want
     * a constrained list of names or else an arbitrary list of identical names.
     * 
     * @param argcount number of arguments
     * @param argnames array of argument names
     */
    public ConfigurationInfo(int argcount, String argnames[])
    {
        this.argcount = argcount;
        this.argnames = argnames;
    }

    public final int getArgCount()
    {
        return argcount;
    }

    protected int argcount = NOT_SET;

    protected String[] defaultArgValues = null;

    /**
     * Get any default values for an argument
     * 
     * @return an array of default argument values.  May be null
     */
    public final String[] getDefaultArgValues()
    {
        return defaultArgValues;
    }

    private static String classToArgName(Class<?> c)
    {
        // we only support builtin classnames!

        String className = c.getName();
        if (className.startsWith("java.lang."))
            className = className.substring("java.lang.".length());

        return className.toLowerCase();
    }

    /**
     * Return the name of each parameter. The default implementation is usually
     * sufficient for simple cases, but one could do wacky things here like
     * support an infinite list of alternating arg names.
     * 
     * @param argnum The argument number.
     * @return name of argument
     */
    public String getArgName(int argnum)
    {
        if (argNameGeneratorClass != null)
        {
            Method getArgNameMethod;
            try
            {
                getArgNameMethod = argNameGeneratorClass.getMethod("getArgumentName", int.class);
                return (String)getArgNameMethod.invoke(null, argnum);
            }
            catch (Exception e)
            {
                // TODO: connect these exception to our problem logging subsystem.
                e.printStackTrace();
            }

            return "";
        }

        if ((argnames == null) || (argnames.length == 0))
        {
            return classToArgName(getArgType(argnum));
        }
        else if (argnum >= argnames.length)
        {
            return argnames[argnames.length - 1];
        }
        else
        {
            return argnames[argnum];
        }
    }

    /**
     * Return the type of each parameter. This is computed based on your setter,
     * and cannot be overridden
     * 
     * @param argnum The argument number.
     */
    public final Class<?> getArgType(int argnum)
    {
        if (argnum >= argtypes.length)
        {
            return argtypes[argtypes.length - 1];
        }
        else
        {
            return argtypes[argnum];
        }
    }

    protected Class<?> argNameGeneratorClass;
    protected String[] argnames;
    protected Class<?>[] argtypes;

    protected String[] prerequisites = null;

    /**
     * Return variable names that should be set before this one. The buffer is
     * always set such that it tries to set all variables at a given level
     * before setting child values, but you could override by using this. Its
     * probably a bad idea to depend on children, though. It is unnecessary to
     * set parent vars as prerequisites, since they are implicitly set first
     */
    public String[] getPrerequisites()
    {
        return prerequisites;
    }

    protected String[] softPrerequisites = null;

    /**
     * Prerequisites which should be set before this one if they exist
     */
    public String[] getSoftPrerequisites()
    {
        return softPrerequisites;
    }

    protected boolean allowMultiple = false;

    /**
     * Variables are generally only allowed to be set once in a given
     * file/cmdline. It is sometimes useful to allow the same set multiple times
     * in order to aggregate values.
     * 
     * @return true if the setter can be called multiple times
     */
    public boolean allowMultiple()
    {
        return allowMultiple;
    }

    protected String[] aliases = null;

    /**
     * Return an array of other names for this variable.
     */
    public String[] getAliases()
    {
        return aliases;
    }

    protected boolean isAdvanced = false;

    /**
     * Override to make a variable hidden by default (i.e. you need -advanced on
     * the cmdline)
     */
    public boolean isAdvanced()
    {
        return isAdvanced;
    }

    protected boolean isHidden = false;

    /**
     * Override to make a variable completely hidden
     */
    public boolean isHidden()
    {
        return isHidden;
    }

    protected boolean isDisplayed = true;

    /**
     * Override to prevent printing when dumping configuration
     */
    public boolean isDisplayed()
    {
        return isDisplayed;
    }

    /**
     * If a variable -must- be set, override this
     */
    public boolean isRequired()
    {
        return isRequired;
    }

    protected boolean isRequired = false;

    /**
     * Magic used by the command line configurator only at the moment to decide
     * whether this variable should eat all subsequent arguments. Useful for
     * -help...
     */
    public boolean isGreedy()
    {
        return isGreedy;
    }

    protected boolean isGreedy = false;

    public boolean isPath()
    {
        return isPath;
    }

    protected boolean isPath = false;

    public boolean doChecksum()
    {
        return true;
    }

    public String getDeprecatedMessage()
    {
        return deprecatedMessage;
    }

    protected String deprecatedMessage = null;

    public boolean isDeprecated()
    {
        return isDeprecated;
    }

    protected boolean isDeprecated = false;

    public String getDeprecatedReplacement()
    {
        return deprecatedReplacement;
    }

    protected String deprecatedReplacement;

    public String getDeprecatedSince()
    {
        return deprecatedSince;
    }

    protected String deprecatedSince;
    
    /**
     * @return True indicates that the option is no longer 
     * supported and will not have any affect.
     */
    public boolean isRemoved() 
    {
        return isRemoved;
    }

    protected boolean isRemoved = false;
    
    /**
     * @return True the option requires Flex in order to be useful. 
     */
    public boolean isRoyaleOnly() 
    {
        return isRoyaleOnly;
    }

    protected boolean isRoyaleOnly = false;
    
    protected final void setSetterMethod(Method setter)
    {
        Class<?>[] pt = setter.getParameterTypes();

        assert (pt.length >= 2) : ("coding error: config setter must take at least 2 args!");

        this.setter = setter;

        if (pt.length == 2)
        {
            Class<?> c = pt[1];

            if (ConfigurationBuffer.isSupportedListType(c))
            {
                if (argcount == NOT_SET)
                    argcount = -1; // infinite list

                argtypes = new Class[] {String.class};
                return;
            }
            else if (ConfigurationBuffer.isSupportedValueType(c))
            {
                assert (argcount == NOT_SET) : ("coding error: value object setter cannot override argcount");
                assert (argnames == null) : ("coding error: value object setter cannot override argnames");

                Field[] fields = c.getFields();

                argcount = fields.length;

                assert (argcount > 0) : ("coding error: " + setter + " value object " + c.getName() + " must contain at least one public field");

                argnames = new String[fields.length];
                argtypes = new Class[fields.length];

                for (int f = 0; f < fields.length; ++f)
                {
                    argnames[f] = ConfigurationBuffer.c2h(fields[f].getName());
                    argtypes[f] = fields[f].getType();
                }
                return;
            }
        }

        assert ((argcount == NOT_SET) || (argcount == pt.length - 1)) : ("coding error: the argument count must match the number of setter arguments");
        // We've taken care of lists and value objects, from here on out, it must match the parameter list.

        argcount = pt.length - 1;

        DefaultArgumentValue defaultArgValuesAnno = setter.getAnnotation(DefaultArgumentValue.class);
        if (defaultArgValuesAnno != null)
            defaultArgValues = defaultArgValuesAnno.value();

        argtypes = new Class[pt.length - 1];
        for (int i = 1; i < pt.length; ++i)
        {
            assert (ConfigurationBuffer.isSupportedSimpleType(pt[i])) : ("coding error: " + setter.getClass().getName() + "." + setter.getName() + " parameter " + i + " is not a supported type!");
            argtypes[i - 1] = pt[i];
        }
    }

    protected final Method getSetterMethod()
    {
        return setter;
    }

    private Method setter;
    private Method getter;

    protected final void setGetterMethod(Method getter)
    {
        this.getter = getter;
    }

    protected final Method getGetterMethod()
    {
        return getter;
    }

    @Override
    public String toString()
    {
        return MoreObjects.toStringHelper("")
                .add("alias", arrayAsString(getAliases()))
                .add("argcount", getArgCount())
                .add("argnames", arrayAsString(argnames))
                .add("argtypes", arrayAsString(argtypes))
                .add("deprecated", isDeprecated())
                .add("deprecatedMessage", getDeprecatedMessage())
                .add("deprecatedReplacement", getDeprecatedReplacement())
                .add("deprecatedSince", getDeprecatedSince())
                .add("getter", getGetterMethod() == null ? "null" : getGetterMethod().getName())
                .add("setter", getSetterMethod() == null ? "null" : getSetterMethod().getName())
                .add("required", isRequired())
                .add("Prerequisites", arrayAsString(getPrerequisites()))
                .add("softPrerequisites", arrayAsString(getSoftPrerequisites()))
                .add("advanced", isAdvanced())
                .add("allow multiple", allowMultiple())
                //.add("doChecksum", doChecksum())
                .add("displayed", isDisplayed())
                .add("greedy", isGreedy())
                .add("hidden", isHidden())
                .add("removed", isRemoved())
                .add("path", isPath())
                .toString();
    }

    private String arrayAsString(Object[] array)
    {
        if (array == null)
            return "";
        else
            return "[" + Joiner.on(",").join(array) + "]";
    }

    /**
     * True if only {@code compc} client can use this option.
     */
    public boolean isCompcOnly = false;
}
