/*
 * Copyright (C) 2011 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.newproject;

import com.android.SdkConstants;
import com.android.annotations.Nullable;
import com.android.ide.common.xml.ManifestData;
import com.android.ide.common.xml.ManifestData.Activity;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.internal.project.ProjectProperties;
import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
import com.android.utils.Pair;
import com.android.xml.AndroidManifest;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.ui.IWorkingSet;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * The {@link NewProjectWizardState} holds the state used by the various pages
 * in the {@link NewProjectWizard} and its variations, and it can also be used
 * to pass project information to the {@link NewProjectCreator}.
 */
public class NewProjectWizardState {
    /** The mode to run the wizard in: creating test, or sample, or plain project */
    public Mode mode;

    /**
     * If true, the project should be created from an existing codebase (pointed
     * to by the {@link #projectLocation} or in the case of sample projects, the
     * {@link #chosenSample}. Otherwise, create a brand new project from scratch.
     */
    public boolean useExisting;

    /**
     * Whether new projects should be created into the default project location
     * (e.g. in the Eclipse workspace) or not
     */
    public boolean useDefaultLocation = true;

    /** The build target SDK */
    public IAndroidTarget target;
    /** True if the user has manually modified the target */
    public boolean targetModifiedByUser;

    /** The location to store projects into */
    public File projectLocation = new File(Platform.getLocation().toOSString());
    /** True if the project location name has been manually edited by the user */
    public boolean projectLocationModifiedByUser;

    /** The name of the project */
    public String projectName = ""; //$NON-NLS-1$
    /** True if the project name has been manually edited by the user */
    public boolean projectNameModifiedByUser;

    /** The application name */
    public String applicationName;
    /** True if the application name has been manually edited by the user */
    public boolean applicationNameModifiedByUser;

    /** The package path */
    public String packageName;
    /** True if the package name has been manually edited by the user */
    public boolean packageNameModifiedByUser;

    /** True if a new activity should be created */
    public boolean createActivity;

    /** The name of the new activity to be created */
    public String activityName;
    /** True if the activity name has been manually edited by the user */
    public boolean activityNameModifiedByUser;

    /** The minimum SDK version to use with the project (may be null or blank) */
    public String minSdk;
    /** True if the minimum SDK version has been manually edited by the user */
    public boolean minSdkModifiedByUser;
    /**
     * A list of paths to each of the available samples for the current SDK.
     * The pair is (String: sample display name => File: sample directory).
     * Note we want a list, not a map since we might have duplicates.
     * */
    public List<Pair<String, File>> samples = new ArrayList<Pair<String, File>>();
    /** Path to the currently chosen sample */
    public File chosenSample;

    /** The name of the source folder, relative to the project root */
    public String sourceFolder = SdkConstants.FD_SOURCES;
    /** The set of chosen working sets to use when creating the project */
    public IWorkingSet[] workingSets = new IWorkingSet[0];

    /**
     * A reference to a different project that the current test project will be
     * testing.
     */
    public IProject testedProject;
    /**
     * If true, this test project should be testing itself, otherwise it will be
     * testing the project pointed to by {@link #testedProject}.
     */
    public boolean testingSelf;

    // NOTE: These apply only to creating paired projects; when isTest is true
    // we're using
    // the normal fields above
    /**
     * If true, create a test project along with this plain project which will
     * be testing the plain project. (This flag only applies when creating
     * normal projects.)
     */
    public boolean createPairProject;
    /**
     * The application name of the test application (only applies when
     * {@link #createPairProject} is true)
     */
    public String testApplicationName;
    /**
     * True if the testing application name has been modified by the user (only
     * applies when {@link #createPairProject} is true)
     */
    public boolean testApplicationNameModified;
    /**
     * The package name of the test application (only applies when
     * {@link #createPairProject} is true)
     */
    public String testPackageName;
    /**
     * True if the testing package name has been modified by the user (only
     * applies when {@link #createPairProject} is true)
     */
    public boolean testPackageModified;
    /**
     * The project name of the test project (only applies when
     * {@link #createPairProject} is true)
     */
    public String testProjectName;
    /**
     * True if the testing project name has been modified by the user (only
     * applies when {@link #createPairProject} is true)
     */
    public boolean testProjectModified;
    /** Package name of the tested app */
    public String testTargetPackageName;

    /**
     * Copy project into workspace? This flag only applies when importing
     * projects (creating projects from existing source)
     */
    public boolean copyIntoWorkspace;

    /**
     * List of projects to be imported. Null if not importing projects.
     */
    @Nullable
    public List<ImportedProject> importProjects;

    /**
     * Creates a new {@link NewProjectWizardState}
     *
     * @param mode the mode to run the wizard in
     */
    public NewProjectWizardState(Mode mode) {
        this.mode = mode;
        if (mode == Mode.SAMPLE) {
            useExisting = true;
        } else if (mode == Mode.TEST) {
            createActivity = false;
        }
    }

    /**
     * Extract information (package name, application name, minimum SDK etc) from
     * the given Android project.
     *
     * @param path the path to the project to extract information from
     */
    public void extractFromAndroidManifest(Path path) {
        String osPath = path.append(SdkConstants.FN_ANDROID_MANIFEST_XML).toOSString();
        if (!(new File(osPath).exists())) {
            return;
        }

        ManifestData manifestData = AndroidManifestHelper.parseForData(osPath);
        if (manifestData == null) {
            return;
        }

        String newPackageName = null;
        Activity activity = null;
        String newActivityName = null;
        String minSdkVersion = null;
        try {
            newPackageName = manifestData.getPackage();
            minSdkVersion = manifestData.getMinSdkVersionString();

            // try to get the first launcher activity. If none, just take the first activity.
            activity = manifestData.getLauncherActivity();
            if (activity == null) {
                Activity[] activities = manifestData.getActivities();
                if (activities != null && activities.length > 0) {
                    activity = activities[0];
                }
            }
        } catch (Exception e) {
            // ignore exceptions
        }

        if (newPackageName != null && newPackageName.length() > 0) {
            packageName = newPackageName;
        }

        if (activity != null) {
            newActivityName = AndroidManifest.extractActivityName(activity.getName(),
                    newPackageName);
        }

        if (newActivityName != null && newActivityName.length() > 0) {
            activityName = newActivityName;
            // we are "importing" an existing activity, not creating a new one
            createActivity = false;

            // If project name and application names are empty, use the activity
            // name as a default. If the activity name has dots, it's a part of a
            // package specification and only the last identifier must be used.
            if (newActivityName.indexOf('.') != -1) {
                String[] ids = newActivityName.split(AdtConstants.RE_DOT);
                newActivityName = ids[ids.length - 1];
            }
            if (projectName == null || projectName.length() == 0 ||
                    !projectNameModifiedByUser) {
                projectName = newActivityName;
                projectNameModifiedByUser = false;
            }
            if (applicationName == null || applicationName.length() == 0 ||
                    !applicationNameModifiedByUser) {
                applicationNameModifiedByUser = false;
                applicationName = newActivityName;
            }
        } else {
            activityName = ""; //$NON-NLS-1$

            // There is no activity name to use to fill in the project and application
            // name. However if there's a package name, we can use this as a base.
            if (newPackageName != null && newPackageName.length() > 0) {
                // Package name is a java identifier, so it's most suitable for
                // an application name.

                if (applicationName == null || applicationName.length() == 0 ||
                        !applicationNameModifiedByUser) {
                    applicationName = newPackageName;
                }

                // For the project name, remove any dots
                newPackageName = newPackageName.replace('.', '_');
                if (projectName == null || projectName.length() == 0 ||
                        !projectNameModifiedByUser) {
                    projectName = newPackageName;
                }

            }
        }

        if (mode == Mode.ANY && useExisting) {
            updateSdkTargetToMatchProject(path.toFile());
        }

        minSdk = minSdkVersion;
        minSdkModifiedByUser = false;
    }

    /**
     * Try to find an SDK Target that matches the current MinSdkVersion.
     *
     * There can be multiple targets with the same sdk api version, so don't change
     * it if it's already at the right version. Otherwise pick the first target
     * that matches.
     */
    public void updateSdkTargetToMatchMinSdkVersion() {
        IAndroidTarget currentTarget = target;
        if (currentTarget != null && currentTarget.getVersion().equals(minSdk)) {
            return;
        }

        Sdk sdk = Sdk.getCurrent();
        if (sdk != null) {
            IAndroidTarget[] targets = sdk.getTargets();
            for (IAndroidTarget t : targets) {
                if (t.getVersion().equals(minSdk)) {
                    target = t;
                    return;
                }
            }
        }
    }

    /**
     * Updates the SDK to reflect the SDK required by the project at the given
     * location
     *
     * @param location the location of the project
     */
    public void updateSdkTargetToMatchProject(File location) {
        // Select the target matching the manifest's sdk or build properties, if any
        IAndroidTarget foundTarget = null;
        // This is the target currently in the UI
        IAndroidTarget currentTarget = target;
        String projectPath = location.getPath();

        // If there's a current target defined, we do not allow to change it when
        // operating in the create-from-sample mode -- since the available sample list
        // is tied to the current target, so changing it would invalidate the project we're
        // trying to load in the first place.
        if (!targetModifiedByUser) {
            ProjectProperties p = ProjectProperties.load(projectPath,
                    PropertyType.PROJECT);
            if (p != null) {
                String v = p.getProperty(ProjectProperties.PROPERTY_TARGET);
                IAndroidTarget desiredTarget = Sdk.getCurrent().getTargetFromHashString(v);
                // We can change the current target if:
                // - we found a new desired target
                // - there is no current target
                // - or the current target can't run the desired target
                if (desiredTarget != null &&
                        (currentTarget == null || !desiredTarget.canRunOn(currentTarget))) {
                    foundTarget = desiredTarget;
                }
            }

            Sdk sdk = Sdk.getCurrent();
            IAndroidTarget[] targets = null;
            if (sdk != null) {
                targets = sdk.getTargets();
            }
            if (targets == null) {
                targets = new IAndroidTarget[0];
            }

            if (foundTarget == null && minSdk != null) {
                // Otherwise try to match the requested min-sdk-version if we find an
                // exact match, regardless of the currently selected target.
                for (IAndroidTarget existingTarget : targets) {
                    if (existingTarget != null &&
                            existingTarget.getVersion().equals(minSdk)) {
                        foundTarget = existingTarget;
                        break;
                    }
                }
            }

            if (foundTarget == null) {
                // Or last attempt, try to match a sample project location and use it
                // if we find an exact match, regardless of the currently selected target.
                for (IAndroidTarget existingTarget : targets) {
                    if (existingTarget != null &&
                            projectPath.startsWith(existingTarget.getLocation())) {
                        foundTarget = existingTarget;
                        break;
                    }
                }
            }
        }

        if (foundTarget != null) {
            target = foundTarget;
        }
    }

    /**
     * Type of project being offered/created by the wizard
     */
    public enum Mode {
        /** Create a sample project. Testing options are not presented. */
        SAMPLE,

        /**
         * Create a test project, either testing itself or some other project.
         * Note that even if in the {@link #ANY} mode, a test project can be
         * created as a *paired* project with the main project, so this flag
         * only means that we are creating *just* a test project
         */
        TEST,

        /**
         * Create an Android project, which can be a plain project, optionally
         * with a paired test project, or a sample project (the first page
         * contains toggles for choosing which
         */
        ANY;
    }
}
