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

import static com.android.SdkConstants.FQCN_GRID_LAYOUT;
import static com.android.SdkConstants.GRID_LAYOUT;

import com.android.SdkConstants;
import com.android.ide.common.resources.configuration.FolderConfiguration;
import com.android.ide.common.xml.XmlFormatStyle;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.AdtUtils;
import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
import com.android.ide.eclipse.adt.internal.editors.IconFactory;
import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlFormatPreferences;
import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlPrettyPrinter;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.RenderPreviewManager;
import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestInfo;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
import com.android.ide.eclipse.adt.internal.project.SupportLibraryHelper;
import com.android.ide.eclipse.adt.internal.wizards.newxmlfile.NewXmlFileCreationPage.TypeInfo;
import com.android.resources.ResourceFolderType;
import com.android.utils.Pair;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PartInitException;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

/**
 * The "New Android XML File Wizard" provides the ability to create skeleton XML
 * resources files for Android projects.
 * <p/>
 * The wizard has one page, {@link NewXmlFileCreationPage}, used to select the project,
 * the resource folder, resource type and file name. It then creates the XML file.
 */
public class NewXmlFileWizard extends Wizard implements INewWizard {
    /** The XML header to write at the top of the XML file */
    public static final String XML_HEADER_LINE = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; //$NON-NLS-1$

    private static final String PROJECT_LOGO_LARGE = "android-64"; //$NON-NLS-1$

    protected static final String MAIN_PAGE_NAME = "newAndroidXmlFilePage"; //$NON-NLS-1$

    private NewXmlFileCreationPage mMainPage;
    private ChooseConfigurationPage mConfigPage;
    private Values mValues;

    @Override
    public void init(IWorkbench workbench, IStructuredSelection selection) {
        setHelpAvailable(false); // TODO have help
        setWindowTitle("New Android XML File");
        setImageDescriptor();

        mValues = new Values();
        mMainPage = createMainPage(mValues);
        mMainPage.setTitle("New Android XML File");
        mMainPage.setDescription("Creates a new Android XML file.");
        mMainPage.setInitialSelection(selection);

        mConfigPage = new ChooseConfigurationPage(mValues);

        // Trigger a check to see if the SDK needs to be reloaded (which will
        // invoke onSdkLoaded asynchronously as needed).
        AdtPlugin.getDefault().refreshSdk();
    }

    /**
     * Creates the wizard page.
     * <p/>
     * Please do NOT override this method.
     * <p/>
     * This is protected so that it can be overridden by unit tests.
     * However the contract of this class is private and NO ATTEMPT will be made
     * to maintain compatibility between different versions of the plugin.
     */
    protected NewXmlFileCreationPage createMainPage(NewXmlFileWizard.Values values) {
        return new NewXmlFileCreationPage(MAIN_PAGE_NAME, values);
    }

    // -- Methods inherited from org.eclipse.jface.wizard.Wizard --
    //
    // The Wizard class implements most defaults and boilerplate code needed by
    // IWizard

    /**
     * Adds pages to this wizard.
     */
    @Override
    public void addPages() {
        addPage(mMainPage);
        addPage(mConfigPage);

    }

    /**
     * Performs any actions appropriate in response to the user having pressed
     * the Finish button, or refuse if finishing now is not permitted: here, it
     * actually creates the workspace project and then switch to the Java
     * perspective.
     *
     * @return True
     */
    @Override
    public boolean performFinish() {
        final Pair<IFile, IRegion> created = createXmlFile();
        if (created == null) {
            return false;
        } else {
            // Open the file
            // This has to be delayed in order for focus handling to work correctly
            AdtPlugin.getDisplay().asyncExec(new Runnable() {
                @Override
                public void run() {
                    IFile file = created.getFirst();
                    IRegion region = created.getSecond();
                    try {
                        IEditorPart editor = AdtPlugin.openFile(file, null,
                                false /*showEditorTab*/);
                        if (editor instanceof AndroidXmlEditor) {
                            final AndroidXmlEditor xmlEditor = (AndroidXmlEditor)editor;
                            if (!xmlEditor.hasMultiplePages()) {
                                xmlEditor.show(region.getOffset(), region.getLength(),
                                        true /* showEditorTab */);
                            }
                        }
                    } catch (PartInitException e) {
                        AdtPlugin.log(e, "Failed to create %1$s: missing type", //$NON-NLS-1$
                                file.getFullPath().toString());
                    }
                }});

            return true;
        }
    }

    // -- Custom Methods --

    private Pair<IFile, IRegion> createXmlFile() {
        IFile file = mValues.getDestinationFile();
        TypeInfo type = mValues.type;
        if (type == null) {
            // this is not expected to happen
            String name = file.getFullPath().toString();
            AdtPlugin.log(IStatus.ERROR, "Failed to create %1$s: missing type", name);  //$NON-NLS-1$
            return null;
        }
        String xmlns = type.getXmlns();
        String root = mMainPage.getRootElement();
        if (root == null) {
            // this is not expected to happen
            AdtPlugin.log(IStatus.ERROR, "Failed to create %1$s: missing root element", //$NON-NLS-1$
                    file.toString());
            return null;
        }

        String attrs = type.getDefaultAttrs(mValues.project, root);
        String child = type.getChild(mValues.project, root);
        return createXmlFile(file, xmlns, root, attrs, child, type.getResFolderType());
    }

    /** Creates a new file using the given root element, namespace and root attributes */
    private static Pair<IFile, IRegion> createXmlFile(IFile file, String xmlns,
            String root, String rootAttributes, String child, ResourceFolderType folderType) {
        String name = file.getFullPath().toString();
        boolean need_delete = false;

        if (file.exists()) {
            if (!AdtPlugin.displayPrompt("New Android XML File",
                String.format("Do you want to overwrite the file %1$s ?", name))) {
                // abort if user selects cancel.
                return null;
            }
            need_delete = true;
        } else {
            AdtUtils.createWsParentDirectory(file.getParent());
        }

        StringBuilder sb = new StringBuilder(XML_HEADER_LINE);

        if (folderType == ResourceFolderType.LAYOUT && root.equals(GRID_LAYOUT)) {
            IProject project = file.getParent().getProject();
            int minSdk = ManifestInfo.get(project).getMinSdkVersion();
            if (minSdk < 14) {
                root = SupportLibraryHelper.getTagFor(project, FQCN_GRID_LAYOUT);
                if (root.equals(FQCN_GRID_LAYOUT)) {
                    root = GRID_LAYOUT;
                }
            }
        }

        sb.append('<').append(root);
        if (xmlns != null) {
            sb.append('\n').append("  xmlns:android=\"").append(xmlns).append('"');  //$NON-NLS-1$
        }

        if (rootAttributes != null) {
            sb.append("\n  ");                       //$NON-NLS-1$
            sb.append(rootAttributes.replace("\n", "\n  "));  //$NON-NLS-1$ //$NON-NLS-2$
        }

        sb.append(">\n");                            //$NON-NLS-1$

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

        boolean autoFormat = AdtPrefs.getPrefs().getUseCustomXmlFormatter();

        // Insert an indented caret. Since the markup here will be reformatted, we need to
        // insert text tokens that the formatter will preserve, which we can then turn back
        // into indentation and a caret offset:
        final String indentToken = "${indent}"; //$NON-NLS-1$
        final String caretToken = "${caret}";   //$NON-NLS-1$
        sb.append(indentToken);
        sb.append(caretToken);
        if (!autoFormat) {
            sb.append('\n');
        }

        sb.append("</").append(root).append(">\n");  //$NON-NLS-1$ //$NON-NLS-2$

        EclipseXmlFormatPreferences formatPrefs = EclipseXmlFormatPreferences.create();
        String fileContents;
        if (!autoFormat) {
            fileContents = sb.toString();
        } else {
            XmlFormatStyle style = EclipseXmlPrettyPrinter.getForFolderType(folderType);
            fileContents = EclipseXmlPrettyPrinter.prettyPrint(sb.toString(), formatPrefs,
                    style, null /*lineSeparator*/);
        }

        // Remove marker tokens and replace them with whitespace
        fileContents = fileContents.replace(indentToken, formatPrefs.getOneIndentUnit());
        int caretOffset = fileContents.indexOf(caretToken);
        if (caretOffset != -1) {
            fileContents = fileContents.replace(caretToken, ""); //$NON-NLS-1$
        }

        String error = null;
        try {
            byte[] buf = fileContents.getBytes("UTF8");    //$NON-NLS-1$
            InputStream stream = new ByteArrayInputStream(buf);
            if (need_delete) {
                file.delete(IResource.KEEP_HISTORY | IResource.FORCE, null /*monitor*/);
            }
            file.create(stream, true /*force*/, null /*progress*/);
            IRegion region = caretOffset != -1 ? new Region(caretOffset, 0) : null;

            // If you introduced a new locale, or new screen variations etc, ensure that
            // the list of render previews is updated if necessary
            if (file.getParent().getName().indexOf('-') != -1
                    && (folderType == ResourceFolderType.LAYOUT
                        || folderType == ResourceFolderType.VALUES)) {
                RenderPreviewManager.bumpRevision();
            }

            return Pair.of(file, region);
        } catch (UnsupportedEncodingException e) {
            error = e.getMessage();
        } catch (CoreException e) {
            error = e.getMessage();
        }

        error = String.format("Failed to generate %1$s: %2$s", name, error);
        AdtPlugin.displayError("New Android XML File", error);
        return null;
    }

    /**
     * Returns true if the New XML Wizard can create new files of the given
     * {@link ResourceFolderType}
     *
     * @param folderType the folder type to create a file for
     * @return true if this wizard can create new files for the given folder type
     */
    public static boolean canCreateXmlFile(ResourceFolderType folderType) {
        TypeInfo typeInfo = NewXmlFileCreationPage.getTypeInfo(folderType);
        return typeInfo != null && (typeInfo.getDefaultRoot(null /*project*/) != null ||
                typeInfo.getRootSeed() instanceof String);
    }

    /**
     * Creates a new XML file using the template according to the given folder type
     *
     * @param project the project to create the file in
     * @param file the file to be created
     * @param folderType the type of folder to look up a template for
     * @return the created file
     */
    public static Pair<IFile, IRegion> createXmlFile(IProject project, IFile file,
            ResourceFolderType folderType) {
        TypeInfo type = NewXmlFileCreationPage.getTypeInfo(folderType);
        String xmlns = type.getXmlns();
        String root = type.getDefaultRoot(project);
        if (root == null) {
            root = type.getRootSeed().toString();
        }
        String attrs = type.getDefaultAttrs(project, root);
        return createXmlFile(file, xmlns, root, attrs, null, folderType);
    }

    /**
     * Returns an image descriptor for the wizard logo.
     */
    private void setImageDescriptor() {
        ImageDescriptor desc = IconFactory.getInstance().getImageDescriptor(PROJECT_LOGO_LARGE);
        setDefaultPageImageDescriptor(desc);
    }

    /**
     * Specific New XML File wizard tied to the {@link ResourceFolderType#LAYOUT} type
     */
    public static class NewLayoutWizard extends NewXmlFileWizard {
        /** Creates a new {@link NewLayoutWizard} */
        public NewLayoutWizard() {
        }

        @Override
        public void init(IWorkbench workbench, IStructuredSelection selection) {
            super.init(workbench, selection);
            setWindowTitle("New Android Layout XML File");
            super.mMainPage.setTitle("New Android Layout XML File");
            super.mMainPage.setDescription("Creates a new Android Layout XML file.");
            super.mMainPage.setInitialFolderType(ResourceFolderType.LAYOUT);
        }
    }

    /**
     * Specific New XML File wizard tied to the {@link ResourceFolderType#VALUES} type
     */
    public static class NewValuesWizard extends NewXmlFileWizard {
        /** Creates a new {@link NewValuesWizard} */
        public NewValuesWizard() {
        }

        @Override
        public void init(IWorkbench workbench, IStructuredSelection selection) {
            super.init(workbench, selection);
            setWindowTitle("New Android Values XML File");
            super.mMainPage.setTitle("New Android Values XML File");
            super.mMainPage.setDescription("Creates a new Android Values XML file.");
            super.mMainPage.setInitialFolderType(ResourceFolderType.VALUES);
        }
    }

    /** Value object which holds the current state of the wizard pages */
    public static class Values {
        /** The currently selected project, or null */
        public IProject project;
        /** The root name of the XML file to create, or null */
        public String name;
        /** The type of XML file to create */
        public TypeInfo type;
        /** The path within the project to create the new file in */
        public String folderPath;
        /** The currently chosen configuration */
        public FolderConfiguration configuration = new FolderConfiguration();

        /**
         * Returns the destination filename or an empty string.
         *
         * @return the filename, never null.
         */
        public String getFileName() {
            String fileName;
            if (name == null) {
                fileName = ""; //$NON-NLS-1$
            } else {
                fileName = name.trim();
                if (fileName.length() > 0 && fileName.indexOf('.') == -1) {
                    fileName = fileName + SdkConstants.DOT_XML;
                }
            }

            return fileName;
        }

        /**
         * Returns a {@link IFile} for the destination file.
         * <p/>
         * Returns null if the project, filename or folder are invalid and the
         * destination file cannot be determined.
         * <p/>
         * The {@link IFile} is a resource. There might or might not be an
         * actual real file.
         *
         * @return an {@link IFile} for the destination file
         */
        public IFile getDestinationFile() {
            String fileName = getFileName();
            if (project != null && folderPath != null && folderPath.length() > 0
                    && fileName.length() > 0) {
                IPath dest = new Path(folderPath).append(fileName);
                IFile file = project.getFile(dest);
                return file;
            }
            return null;
        }
    }
}
