/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
 *
 * 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 com.android.ide.eclipse.adt.internal.wizards.templates;

import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_PACKAGE_NAME;
import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_CONSTRAINTS;
import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_DEFAULT;
import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_HELP;
import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_ID;
import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_NAME;
import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_SUGGEST;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.DomUtilities;
import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestInfo;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
import com.android.ide.eclipse.adt.internal.resources.ResourceNameValidator;
import com.android.ide.eclipse.adt.internal.wizards.newproject.ApplicationInfoPage;
import com.android.resources.ResourceFolderType;
import com.android.resources.ResourceType;
import com.google.common.base.Splitter;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.swt.widgets.Control;
import org.w3c.dom.Element;

import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Locale;

/**
 * A template parameter editable and edited by the user.
 * <p>
 * Note that this class encapsulates not just the metadata provided by the
 * template, but the actual editing operation of that template in the wizard: it
 * also captures current values, a reference to the editing widget (such that
 * related widgets can be updated when one value depends on another etc)
 */
class Parameter {
    enum Type {
        STRING,
        BOOLEAN,
        ENUM,
        SEPARATOR;
        // TODO: Numbers?

        public static Type get(String name) {
            try {
                return Type.valueOf(name.toUpperCase(Locale.US));
            } catch (IllegalArgumentException e) {
                AdtPlugin.printErrorToConsole("Unexpected template type '" + name + "'");
                AdtPlugin.printErrorToConsole("Expected one of :");
                for (Type s : Type.values()) {
                    AdtPlugin.printErrorToConsole("  " + s.name().toLowerCase(Locale.US));
                }
            }

            return STRING;
        }
    }

    /**
     * Constraints that can be applied to a parameter which helps the UI add a
     * validator etc for user input. These are typically combined into a set
     * of constraints via an EnumSet.
     */
    enum Constraint {
        /**
         * This value must be unique. This constraint usually only makes sense
         * when other constraints are specified, such as {@link #LAYOUT}, which
         * means that the parameter should designate a name that does not
         * represent an existing layout resource name
         */
        UNIQUE,

        /**
         * This value must already exist. This constraint usually only makes sense
         * when other constraints are specified, such as {@link #LAYOUT}, which
         * means that the parameter should designate a name that already exists as
         * a resource name.
         */
        EXISTS,

        /** The associated value must not be empty */
        NONEMPTY,

        /** The associated value is allowed to be empty */
        EMPTY,

        /** The associated value should represent a fully qualified activity class name */
        ACTIVITY,

        /** The associated value should represent an API level */
        APILEVEL,

        /** The associated value should represent a valid class name */
        CLASS,

        /** The associated value should represent a valid package name */
        PACKAGE,

        /** The associated value should represent a valid layout resource name */
        LAYOUT,

        /** The associated value should represent a valid drawable resource name */
        DRAWABLE,

        /** The associated value should represent a valid id resource name */
        ID,

        /** The associated value should represent a valid string resource name */
        STRING;

        public static Constraint get(String name) {
            try {
                return Constraint.valueOf(name.toUpperCase(Locale.US));
            } catch (IllegalArgumentException e) {
                AdtPlugin.printErrorToConsole("Unexpected template constraint '" + name + "'");
                if (name.indexOf(',') != -1) {
                    AdtPlugin.printErrorToConsole("Use | to separate constraints");
                } else {
                    AdtPlugin.printErrorToConsole("Expected one of :");
                    for (Constraint s : Constraint.values()) {
                        AdtPlugin.printErrorToConsole("  " + s.name().toLowerCase(Locale.US));
                    }
                }
            }

            return NONEMPTY;
        }
    }

    /** The template defining the parameter */
    public final TemplateMetadata template;

    /** The type of parameter */
    @NonNull
    public final Type type;

    /** The unique id of the parameter (not displayed to the user) */
    @Nullable
    public final String id;

    /** The display name for this parameter */
    @Nullable
    public final String name;

    /**
     * The initial value for this parameter (see also {@link #suggest} for more
     * dynamic defaults
     */
    @Nullable
    public final String initial;

    /**
     * A template expression using other template parameters for producing a
     * default value based on other edited parameters, if possible.
     */
    @Nullable
    public final String suggest;

    /** Help for the parameter, if any */
    @Nullable
    public final String help;

    /** The currently edited value */
    @Nullable
    public Object value;

    /** The control showing this value */
    @Nullable
    public Control control;

    /** The decoration associated with the control */
    @Nullable
    public ControlDecoration decoration;

    /** Whether the parameter has been edited */
    public boolean edited;

    /** The element defining this parameter */
    @NonNull
    public final Element element;

    /** The constraints applicable for this parameter */
    @NonNull
    public final EnumSet<Constraint> constraints;

    /** The validator, if any, for this field */
    private IInputValidator mValidator;

    /** True if this field has no validator */
    private boolean mNoValidator;

    /** Project associated with this validator */
    private IProject mValidatorProject;

    Parameter(@NonNull TemplateMetadata template, @NonNull Element parameter) {
        this.template = template;
        element = parameter;

        String typeName = parameter.getAttribute(TemplateHandler.ATTR_TYPE);
        assert typeName != null && !typeName.isEmpty() : TemplateHandler.ATTR_TYPE;
        type = Type.get(typeName);

        id = parameter.getAttribute(ATTR_ID);
        initial = parameter.getAttribute(ATTR_DEFAULT);
        suggest = parameter.getAttribute(ATTR_SUGGEST);
        name = parameter.getAttribute(ATTR_NAME);
        help = parameter.getAttribute(ATTR_HELP);
        String constraintString = parameter.getAttribute(ATTR_CONSTRAINTS);
        if (constraintString != null && !constraintString.isEmpty()) {
            EnumSet<Constraint> constraintSet = null;
            for (String s : Splitter.on('|').omitEmptyStrings().split(constraintString)) {
                Constraint constraint = Constraint.get(s);
                if (constraintSet == null) {
                    constraintSet = EnumSet.of(constraint);
                } else {
                    constraintSet = EnumSet.copyOf(constraintSet);
                    constraintSet.add(constraint);
                }
            }
            constraints = constraintSet;
        } else {
            constraints = EnumSet.noneOf(Constraint.class);
        }

        if (initial != null && !initial.isEmpty() && type == Type.BOOLEAN) {
            value = Boolean.valueOf(initial);
        } else {
            value = initial;
        }
    }

    Parameter(
            @NonNull TemplateMetadata template,
            @NonNull Type type,
            @NonNull String id,
            @NonNull String initialValue) {
        this.template = template;
        this.type = type;
        this.id = id;
        this.value = initialValue;
        element = null;
        initial = null;
        suggest = null;
        name = id;
        help = null;
        constraints = EnumSet.noneOf(Constraint.class);
    }

    List<Element> getOptions() {
        if (element != null) {
            return DomUtilities.getChildren(element);
        } else {
            return Collections.emptyList();
        }
    }

    @Nullable
    public IInputValidator getValidator(@Nullable final IProject project) {
        if (mNoValidator) {
            return null;
        }

        if (project != mValidatorProject) {
            // Force update of validators if the project changes, since the validators
            // are often tied to project metadata (for example, the resource name validators
            // which look for name conflicts)
            mValidator = null;
            mValidatorProject = project;
        }

        if (mValidator == null) {
            if (constraints.contains(Constraint.LAYOUT)) {
                if (project != null && constraints.contains(Constraint.UNIQUE)) {
                    mValidator = ResourceNameValidator.create(false, project, ResourceType.LAYOUT);
                } else {
                    mValidator = ResourceNameValidator.create(false, ResourceFolderType.LAYOUT);
                }
                return mValidator;
            } else if (constraints.contains(Constraint.STRING)) {
                if (project != null && constraints.contains(Constraint.UNIQUE)) {
                    mValidator = ResourceNameValidator.create(false, project, ResourceType.STRING);
                } else {
                    mValidator = ResourceNameValidator.create(false, ResourceFolderType.VALUES);
                }
                return mValidator;
            } else if (constraints.contains(Constraint.ID)) {
                if (project != null && constraints.contains(Constraint.UNIQUE)) {
                    mValidator = ResourceNameValidator.create(false, project, ResourceType.ID);
                } else {
                    mValidator = ResourceNameValidator.create(false, ResourceFolderType.VALUES);
                }
                return mValidator;
            } else if (constraints.contains(Constraint.DRAWABLE)) {
                if (project != null && constraints.contains(Constraint.UNIQUE)) {
                    mValidator = ResourceNameValidator.create(false, project,
                            ResourceType.DRAWABLE);
                } else {
                    mValidator = ResourceNameValidator.create(false, ResourceFolderType.DRAWABLE);
                }
                return mValidator;
            } else if (constraints.contains(Constraint.PACKAGE)
                    || constraints.contains(Constraint.CLASS)
                    || constraints.contains(Constraint.ACTIVITY)) {
                mValidator = new IInputValidator() {
                    @Override
                    public String isValid(String newText) {
                        newText = newText.trim();
                        if (newText.isEmpty()) {
                            if (constraints.contains(Constraint.EMPTY)) {
                                return null;
                            } else if (constraints.contains(Constraint.NONEMPTY)) {
                                return String.format("Enter a value for %1$s", name);
                            } else {
                                // Compatibility mode: older templates might not specify;
                                // in that case, accept empty
                                if (!"activityClass".equals(id)) { //$NON-NLS-1$
                                    return null;
                                }
                            }
                        }
                        IStatus status;
                        if (constraints.contains(Constraint.ACTIVITY)) {
                            status = ApplicationInfoPage.validateActivity(newText);
                        } else if (constraints.contains(Constraint.PACKAGE)) {
                            status = ApplicationInfoPage.validatePackage(newText);
                        } else {
                            assert constraints.contains(Constraint.CLASS);
                            status = ApplicationInfoPage.validateClass(newText);
                        }
                        if (status != null && !status.isOK()) {
                            return status.getMessage();
                        }

                        // Uniqueness
                        if (project != null && constraints.contains(Constraint.UNIQUE)) {
                            try {
                                // Determine the package.
                                // If there is a package info

                                IJavaProject p = BaseProjectHelper.getJavaProject(project);
                                if (p != null) {
                                    String fqcn = newText;
                                    if (fqcn.indexOf('.') == -1) {
                                        String pkg = null;
                                        Parameter parameter = template.getParameter(
                                                ATTR_PACKAGE_NAME);
                                        if (parameter != null && parameter.value != null) {
                                            pkg = parameter.value.toString();
                                        } else {
                                            pkg = ManifestInfo.get(project).getPackage();
                                        }
                                        fqcn = pkg.isEmpty() ? newText : pkg + '.' + newText;
                                    }

                                    IType t = p.findType(fqcn);
                                    if (t != null && t.exists()) {
                                        return String.format("%1$s already exists", newText);
                                    }
                                }
                            } catch (CoreException e) {
                                AdtPlugin.log(e, null);
                            }
                        }

                        return null;
                    }
                };
                return mValidator;
            } else if (constraints.contains(Constraint.NONEMPTY)) {
                mValidator = new IInputValidator() {
                    @Override
                    public String isValid(String newText) {
                        if (newText.trim().isEmpty()) {
                            return String.format("Enter a value for %1$s", name);
                        }

                        return null;
                    }
                };
                return mValidator;
            }

            // TODO: Handle EXISTS, APILEVEL (which is currently handled manually in the
            // new project wizard, and never actually input by the user in a templated
            // wizard)

            mNoValidator = true;
        }

        return mValidator;
    }
}