/*
 * 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.SdkConstants.ATTR_PACKAGE;
import static com.android.SdkConstants.DOT_AIDL;
import static com.android.SdkConstants.DOT_FTL;
import static com.android.SdkConstants.DOT_JAVA;
import static com.android.SdkConstants.DOT_RS;
import static com.android.SdkConstants.DOT_SVG;
import static com.android.SdkConstants.DOT_TXT;
import static com.android.SdkConstants.DOT_XML;
import static com.android.SdkConstants.EXT_XML;
import static com.android.SdkConstants.FD_NATIVE_LIBS;
import static com.android.SdkConstants.XMLNS_PREFIX;
import static com.android.ide.eclipse.adt.internal.wizards.templates.InstallDependencyPage.SUPPORT_LIBRARY_NAME;
import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateManager.getTemplateRootFolder;

import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.annotations.VisibleForTesting;
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.actions.AddSupportJarAction;
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.DomUtilities;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
import com.android.ide.eclipse.adt.internal.sdk.AdtManifestMergeCallback;
import com.android.manifmerger.ManifestMerger;
import com.android.manifmerger.MergerLog;
import com.android.resources.ResourceFolderType;
import com.android.utils.SdkUtils;
import com.google.common.base.Charsets;
import com.google.common.collect.Lists;
import com.google.common.io.Files;

import freemarker.cache.TemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;

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.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.ToolFactory;
import org.eclipse.jdt.core.formatter.CodeFormatter;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.NullChange;
import org.eclipse.ltk.core.refactoring.TextFileChange;
import org.eclipse.swt.SWT;
import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

/**
 * Handler which manages instantiating FreeMarker templates, copying resources
 * and merging into existing files
 */
class TemplateHandler {
    /** Highest supported format; templates with a higher number will be skipped
     * <p>
     * <ul>
     * <li> 1: Initial format, supported by ADT 20 and up.
     * <li> 2: ADT 21 and up. Boolean variables that have a default value and are not
     *    edited by the user would end up as strings in ADT 20; now they are always
     *    proper Booleans. Templates which rely on this should specify format >= 2.
     * <li> 3: The wizard infrastructure passes the {@code isNewProject} boolean variable
     *    to indicate whether a wizard is created as part of a new blank project
     * <li> 4: The templates now specify dependencies in the recipe file.
     * </ul>
     */
    static final int CURRENT_FORMAT = 4;

    /**
     * Special marker indicating that this path refers to the special shared
     * resource directory rather than being somewhere inside the root/ directory
     * where all template specific resources are found
     */
    private static final String VALUE_TEMPLATE_DIR = "$TEMPLATEDIR"; //$NON-NLS-1$

    /**
     * Directory within the template which contains the resources referenced
     * from the template.xml file
     */
    private static final String DATA_ROOT = "root";      //$NON-NLS-1$

    /**
     * Shared resource directory containing common resources shared among
     * multiple templates
     */
    private static final String RESOURCE_ROOT = "resources";   //$NON-NLS-1$

    /** Reserved filename which describes each template */
    static final String TEMPLATE_XML = "template.xml";   //$NON-NLS-1$

    // Various tags and attributes used in the template metadata files - template.xml,
    // globals.xml.ftl, recipe.xml.ftl, etc.

    static final String TAG_MERGE = "merge";             //$NON-NLS-1$
    static final String TAG_EXECUTE = "execute";         //$NON-NLS-1$
    static final String TAG_GLOBALS = "globals";         //$NON-NLS-1$
    static final String TAG_GLOBAL = "global";           //$NON-NLS-1$
    static final String TAG_PARAMETER = "parameter";     //$NON-NLS-1$
    static final String TAG_COPY = "copy";               //$NON-NLS-1$
    static final String TAG_INSTANTIATE = "instantiate"; //$NON-NLS-1$
    static final String TAG_OPEN = "open";               //$NON-NLS-1$
    static final String TAG_THUMB = "thumb";             //$NON-NLS-1$
    static final String TAG_THUMBS = "thumbs";           //$NON-NLS-1$
    static final String TAG_DEPENDENCY = "dependency";   //$NON-NLS-1$
    static final String TAG_ICONS = "icons";             //$NON-NLS-1$
    static final String TAG_FORMFACTOR = "formfactor";   //$NON-NLS-1$
    static final String TAG_CATEGORY = "category";       //$NON-NLS-1$
    static final String ATTR_FORMAT = "format";          //$NON-NLS-1$
    static final String ATTR_REVISION = "revision";      //$NON-NLS-1$
    static final String ATTR_VALUE = "value";            //$NON-NLS-1$
    static final String ATTR_DEFAULT = "default";        //$NON-NLS-1$
    static final String ATTR_SUGGEST = "suggest";        //$NON-NLS-1$
    static final String ATTR_ID = "id";                  //$NON-NLS-1$
    static final String ATTR_NAME = "name";              //$NON-NLS-1$
    static final String ATTR_DESCRIPTION = "description";//$NON-NLS-1$
    static final String ATTR_TYPE = "type";              //$NON-NLS-1$
    static final String ATTR_HELP = "help";              //$NON-NLS-1$
    static final String ATTR_FILE = "file";              //$NON-NLS-1$
    static final String ATTR_TO = "to";                  //$NON-NLS-1$
    static final String ATTR_FROM = "from";              //$NON-NLS-1$
    static final String ATTR_CONSTRAINTS = "constraints";//$NON-NLS-1$
    static final String ATTR_BACKGROUND = "background";  //$NON-NLS-1$
    static final String ATTR_FOREGROUND = "foreground";  //$NON-NLS-1$
    static final String ATTR_SHAPE = "shape";            //$NON-NLS-1$
    static final String ATTR_TRIM = "trim";              //$NON-NLS-1$
    static final String ATTR_PADDING = "padding";        //$NON-NLS-1$
    static final String ATTR_SOURCE_TYPE = "source";     //$NON-NLS-1$
    static final String ATTR_CLIPART_NAME = "clipartName";//$NON-NLS-1$
    static final String ATTR_TEXT = "text";              //$NON-NLS-1$
    static final String ATTR_SRC_DIR = "srcDir";         //$NON-NLS-1$
    static final String ATTR_SRC_OUT = "srcOut";         //$NON-NLS-1$
    static final String ATTR_RES_DIR = "resDir";         //$NON-NLS-1$
    static final String ATTR_RES_OUT = "resOut";         //$NON-NLS-1$
    static final String ATTR_MANIFEST_DIR = "manifestDir";//$NON-NLS-1$
    static final String ATTR_MANIFEST_OUT = "manifestOut";//$NON-NLS-1$
    static final String ATTR_PROJECT_DIR = "projectDir"; //$NON-NLS-1$
    static final String ATTR_PROJECT_OUT = "projectOut"; //$NON-NLS-1$
    static final String ATTR_MAVEN_URL = "mavenUrl";     //$NON-NLS-1$
    static final String ATTR_DEBUG_KEYSTORE_SHA1 = 
    		"debugKeystoreSha1";                         //$NON-NLS-1$

    static final String CATEGORY_ACTIVITIES = "activities";//$NON-NLS-1$
    static final String CATEGORY_PROJECTS = "projects";    //$NON-NLS-1$
    static final String CATEGORY_OTHER = "other";          //$NON-NLS-1$

    static final String MAVEN_SUPPORT_V4 = "support-v4";   //$NON-NLS-1$
    static final String MAVEN_SUPPORT_V13 = "support-v13"; //$NON-NLS-1$
    static final String MAVEN_APPCOMPAT = "appcompat-v7";  //$NON-NLS-1$

    /** Default padding to apply in wizards around the thumbnail preview images */
    static final int PREVIEW_PADDING = 10;

    /** Default width to scale thumbnail preview images in wizards to */
    static final int PREVIEW_WIDTH = 200;

    /**
     * List of files to open after the wizard has been created (these are
     * identified by {@link #TAG_OPEN} elements in the recipe file
     */
    private final List<String> mOpen = Lists.newArrayList();

    /**
     * List of actions to perform after the wizard has finished.
     */
    protected List<Runnable> mFinalizingActions = Lists.newArrayList();

    /** Path to the directory containing the templates */
    @NonNull
    private final File mRootPath;

    /** The changes being processed by the template handler */
    private List<Change> mMergeChanges;
    private List<Change> mTextChanges;
    private List<Change> mOtherChanges;

    /** The project to write the template into */
    private IProject mProject;

    /** The template loader which is responsible for finding (and sharing) template files */
    private final MyTemplateLoader mLoader;

    /** Agree to all file-overwrites from now on? */
    private boolean mYesToAll = false;

    /** Is writing the template cancelled? */
    private boolean mNoToAll = false;

    /**
     * Should files that we merge contents into be backed up? If yes, will
     * create emacs-style tilde-file backups (filename.xml~)
     */
    private boolean mBackupMergedFiles = true;

    /**
     * Template metadata
     */
    private TemplateMetadata mTemplate;

    private final TemplateManager mManager;

    /** Creates a new {@link TemplateHandler} for the given root path */
    static TemplateHandler createFromPath(File rootPath) {
        return new TemplateHandler(rootPath, new TemplateManager());
    }

    /** Creates a new {@link TemplateHandler} for the template name, which should
     * be relative to the templates directory */
    static TemplateHandler createFromName(String category, String name) {
        TemplateManager manager = new TemplateManager();

        // Use the TemplateManager iteration which should merge contents between the
        // extras/templates/ and tools/templates folders and pick the most recent version
        List<File> templates = manager.getTemplates(category);
        for (File file : templates) {
            if (file.getName().equals(name) && category.equals(file.getParentFile().getName())) {
                return new TemplateHandler(file, manager);
            }
        }

        return new TemplateHandler(new File(getTemplateRootFolder(),
                category + File.separator + name), manager);
    }

    private TemplateHandler(File rootPath, TemplateManager manager) {
        mRootPath = rootPath;
        mManager = manager;
        mLoader = new MyTemplateLoader();
        mLoader.setPrefix(mRootPath.getPath());
    }

    public TemplateManager getManager() {
        return mManager;
    }

    public void setBackupMergedFiles(boolean backupMergedFiles) {
        mBackupMergedFiles = backupMergedFiles;
    }

    @NonNull
    public List<Change> render(IProject project, Map<String, Object> args) {
        mOpen.clear();

        mProject = project;
        mMergeChanges = new ArrayList<Change>();
        mTextChanges = new ArrayList<Change>();
        mOtherChanges = new ArrayList<Change>();

        // Render the instruction list template.
        Map<String, Object> paramMap = createParameterMap(args);
        Configuration freemarker = new Configuration();
        freemarker.setObjectWrapper(new DefaultObjectWrapper());
        freemarker.setTemplateLoader(mLoader);

        processVariables(freemarker, TEMPLATE_XML, paramMap);

        // Add the changes in the order where merges are shown first, then text files,
        // and finally other files (like jars and icons which don't have previews).
        List<Change> changes = new ArrayList<Change>();
        changes.addAll(mMergeChanges);
        changes.addAll(mTextChanges);
        changes.addAll(mOtherChanges);
        return changes;
    }

    Map<String, Object> createParameterMap(Map<String, Object> args) {
        final Map<String, Object> paramMap = createBuiltinMap();

        // Wizard parameters supplied by user, specific to this template
        paramMap.putAll(args);

        return paramMap;
    }

    /** Data model for the templates */
    static Map<String, Object> createBuiltinMap() {
        // Create the data model.
        final Map<String, Object> paramMap = new HashMap<String, Object>();

        // Builtin conversion methods
        paramMap.put("slashedPackageName", new FmSlashedPackageNameMethod());       //$NON-NLS-1$
        paramMap.put("camelCaseToUnderscore", new FmCamelCaseToUnderscoreMethod()); //$NON-NLS-1$
        paramMap.put("underscoreToCamelCase", new FmUnderscoreToCamelCaseMethod()); //$NON-NLS-1$
        paramMap.put("activityToLayout", new FmActivityToLayoutMethod());           //$NON-NLS-1$
        paramMap.put("layoutToActivity", new FmLayoutToActivityMethod());           //$NON-NLS-1$
        paramMap.put("classToResource", new FmClassNameToResourceMethod());         //$NON-NLS-1$
        paramMap.put("escapeXmlAttribute", new FmEscapeXmlStringMethod());          //$NON-NLS-1$
        paramMap.put("escapeXmlText", new FmEscapeXmlStringMethod());               //$NON-NLS-1$
        paramMap.put("escapeXmlString", new FmEscapeXmlStringMethod());             //$NON-NLS-1$
        paramMap.put("extractLetters", new FmExtractLettersMethod());               //$NON-NLS-1$

        // This should be handled better: perhaps declared "required packages" as part of the
        // inputs? (It would be better if we could conditionally disable template based
        // on availability)
        Map<String, String> builtin = new HashMap<String, String>();
        builtin.put("templatesRes", VALUE_TEMPLATE_DIR); //$NON-NLS-1$
        paramMap.put("android", builtin);                //$NON-NLS-1$

        return paramMap;
    }

    static void addDirectoryParameters(Map<String, Object> parameters, IProject project) {
        IPath srcDir = project.getFile(SdkConstants.SRC_FOLDER).getProjectRelativePath();
        parameters.put(ATTR_SRC_DIR, srcDir.toString());

        IPath resDir = project.getFile(SdkConstants.RES_FOLDER).getProjectRelativePath();
        parameters.put(ATTR_RES_DIR, resDir.toString());

        IPath manifestDir = project.getProjectRelativePath();
        parameters.put(ATTR_MANIFEST_DIR, manifestDir.toString());
        parameters.put(ATTR_MANIFEST_OUT, manifestDir.toString());
        
        parameters.put(ATTR_PROJECT_DIR, manifestDir.toString());
        parameters.put(ATTR_PROJECT_OUT, manifestDir.toString());
        
        parameters.put(ATTR_DEBUG_KEYSTORE_SHA1, "");
    }

    @Nullable
    public TemplateMetadata getTemplate() {
        if (mTemplate == null) {
            mTemplate = mManager.getTemplate(mRootPath);
        }

        return mTemplate;
    }

    @NonNull
    public String getResourcePath(String templateName) {
        return new File(mRootPath.getPath(), templateName).getPath();
    }

    /**
     * Load a text resource for the given relative path within the template
     *
     * @param relativePath relative path within the template
     * @return the string contents of the template text file
     */
    @Nullable
    public String readTemplateTextResource(@NonNull String relativePath) {
        try {
            return Files.toString(new File(mRootPath,
                    relativePath.replace('/', File.separatorChar)), Charsets.UTF_8);
        } catch (IOException e) {
            AdtPlugin.log(e, null);
            return null;
        }
    }

    @Nullable
    public String readTemplateTextResource(@NonNull File file) {
        assert file.isAbsolute();
        try {
            return Files.toString(file, Charsets.UTF_8);
        } catch (IOException e) {
            AdtPlugin.log(e, null);
            return null;
        }
    }

    /**
     * Reads the contents of a resource
     *
     * @param relativePath the path relative to the template directory
     * @return the binary data read from the file
     */
    @Nullable
    public byte[] readTemplateResource(@NonNull String relativePath) {
        try {
            return Files.toByteArray(new File(mRootPath, relativePath));
        } catch (IOException e) {
            AdtPlugin.log(e, null);
            return null;
        }
    }

    /**
     * Most recent thrown exception during template instantiation. This should
     * basically always be null. Used by unit tests to see if any template
     * instantiation recorded a failure.
     */
    @VisibleForTesting
    public static Exception sMostRecentException;

    /** Read the given FreeMarker file and process the variable definitions */
    private void processVariables(final Configuration freemarker,
            String file, final Map<String, Object> paramMap) {
        try {
            String xml;
            if (file.endsWith(DOT_XML)) {
                // Just read the file
                xml = readTemplateTextResource(file);
                if (xml == null) {
                    return;
                }
            } else {
                mLoader.setTemplateFile(new File(mRootPath, file));
                Template inputsTemplate = freemarker.getTemplate(file);
                StringWriter out = new StringWriter();
                inputsTemplate.process(paramMap, out);
                out.flush();
                xml = out.toString();
            }

            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();
            saxParser.parse(new ByteArrayInputStream(xml.getBytes()), new DefaultHandler() {
                @Override
                public void startElement(String uri, String localName, String name,
                        Attributes attributes)
                                throws SAXException {
                    if (TAG_PARAMETER.equals(name)) {
                        String id = attributes.getValue(ATTR_ID);
                        if (!paramMap.containsKey(id)) {
                            String value = attributes.getValue(ATTR_DEFAULT);
                            Object mapValue = value;
                            if (value != null && !value.isEmpty()) {
                                String type = attributes.getValue(ATTR_TYPE);
                                if ("boolean".equals(type)) { //$NON-NLS-1$
                                    mapValue = Boolean.valueOf(value);
                                }
                            }
                            paramMap.put(id, mapValue);
                        }
                    } else if (TAG_GLOBAL.equals(name)) {
                        String id = attributes.getValue(ATTR_ID);
                        if (!paramMap.containsKey(id)) {
                        	paramMap.put(id, TypedVariable.parseGlobal(attributes));
                        }
                    } else if (TAG_GLOBALS.equals(name)) {
                        // Handle evaluation of variables
                        String path = attributes.getValue(ATTR_FILE);
                        if (path != null) {
                            processVariables(freemarker, path, paramMap);
                        } // else: <globals> root element
                    } else if (TAG_EXECUTE.equals(name)) {
                        String path = attributes.getValue(ATTR_FILE);
                        if (path != null) {
                            execute(freemarker, path, paramMap);
                        }
                    } else if (TAG_DEPENDENCY.equals(name)) {
                        String dependencyName = attributes.getValue(ATTR_NAME);
                        if (dependencyName.equals(SUPPORT_LIBRARY_NAME)) {
                            // We assume the revision requirement has been satisfied
                            // by the wizard
                            File path = AddSupportJarAction.getSupportJarFile();
                            if (path != null) {
                                IPath to = getTargetPath(FD_NATIVE_LIBS +'/' + path.getName());
                                try {
                                    copy(path, to);
                                } catch (IOException ioe) {
                                    AdtPlugin.log(ioe, null);
                                }
                            }
                        }
                    } else if (!name.equals("template") && !name.equals(TAG_CATEGORY) &&
                    		!name.equals(TAG_FORMFACTOR) && !name.equals("option") &&
                    		!name.equals(TAG_THUMBS) && !name.equals(TAG_THUMB) &&
                    		!name.equals(TAG_ICONS)) {
                        System.err.println("WARNING: Unknown template directive " + name);
                    }
                }
            });
        } catch (Exception e) {
            sMostRecentException = e;
            AdtPlugin.log(e, null);
        }
    }

    @SuppressWarnings("unused")
    private boolean canOverwrite(File file) {
        if (file.exists()) {
            // Warn that the file already exists and ask the user what to do
            if (!mYesToAll) {
                MessageDialog dialog = new MessageDialog(null, "File Already Exists", null,
                        String.format(
                                "%1$s already exists.\nWould you like to replace it?",
                                file.getPath()),
                                MessageDialog.QUESTION, new String[] {
                    // Yes will be moved to the end because it's the default
                    "Yes", "No", "Cancel", "Yes to All"
                }, 0);
                int result = dialog.open();
                switch (result) {
                case 0:
                    // Yes
                    break;
                case 3:
                    // Yes to all
                    mYesToAll = true;
                    break;
                case 1:
                    // No
                    return false;
                case SWT.DEFAULT:
                case 2:
                    // Cancel
                    mNoToAll = true;
                    return false;
                }
            }

            if (mBackupMergedFiles) {
                return makeBackup(file);
            } else {
                return file.delete();
            }
        }

        return true;
    }

    /** Executes the given recipe file: copying, merging, instantiating, opening files etc */
    private void execute(
            final Configuration freemarker,
            String file,
            final Map<String, Object> paramMap) {
        try {
            mLoader.setTemplateFile(new File(mRootPath, file));
            Template freemarkerTemplate = freemarker.getTemplate(file);

            StringWriter out = new StringWriter();
            freemarkerTemplate.process(paramMap, out);
            out.flush();
            String xml = out.toString();

            // Parse and execute the resulting instruction list.
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();

            saxParser.parse(new ByteArrayInputStream(xml.getBytes()),
                    new DefaultHandler() {
                @Override
                public void startElement(String uri, String localName, String name,
                        Attributes attributes)
                                throws SAXException {
                    if (mNoToAll) {
                        return;
                    }

                    try {
                        boolean instantiate = TAG_INSTANTIATE.equals(name);
                        if (TAG_COPY.equals(name) || instantiate) {
                            String fromPath = attributes.getValue(ATTR_FROM);
                            String toPath = attributes.getValue(ATTR_TO);
                            if (toPath == null || toPath.isEmpty()) {
                                toPath = attributes.getValue(ATTR_FROM);
                                toPath = AdtUtils.stripSuffix(toPath, DOT_FTL);
                            }
                            IPath to = getTargetPath(toPath);
                            if (instantiate) {
                                instantiate(freemarker, paramMap, fromPath, to);
                            } else {
                                copyTemplateResource(fromPath, to);
                            }
                        } else if (TAG_MERGE.equals(name)) {
                            String fromPath = attributes.getValue(ATTR_FROM);
                            String toPath = attributes.getValue(ATTR_TO);
                            if (toPath == null || toPath.isEmpty()) {
                                toPath = attributes.getValue(ATTR_FROM);
                                toPath = AdtUtils.stripSuffix(toPath, DOT_FTL);
                            }
                            // Resources in template.xml are located within root/
                            IPath to = getTargetPath(toPath);
                            merge(freemarker, paramMap, fromPath, to);
                        } else if (name.equals(TAG_OPEN)) {
                            // The relative path here is within the output directory:
                            String relativePath = attributes.getValue(ATTR_FILE);
                            if (relativePath != null && !relativePath.isEmpty()) {
                                mOpen.add(relativePath);
                            }
                        } else if (TAG_DEPENDENCY.equals(name)) {
                            String dependencyUrl = attributes.getValue(ATTR_MAVEN_URL);
                            File path;
                            if (dependencyUrl.contains(MAVEN_SUPPORT_V4)) {
                                // We assume the revision requirement has been satisfied
                                // by the wizard
                                path = AddSupportJarAction.getSupportJarFile();
                            } else if (dependencyUrl.contains(MAVEN_SUPPORT_V13)) {
                                path = AddSupportJarAction.getSupport13JarFile();
                            } else if (dependencyUrl.contains(MAVEN_APPCOMPAT)) {
                                path = null;
                                mFinalizingActions.add(new Runnable() {
                                    @Override
                                    public void run() {
                                        AddSupportJarAction.installAppCompatLibrary(mProject, true);
                                    }
                                });
                            } else {
                                path = null;
                                System.err.println("WARNING: Unknown dependency type");
                            }

                            if (path != null) {
                                IPath to = getTargetPath(FD_NATIVE_LIBS +'/' + path.getName());
                                try {
                                    copy(path, to);
                                } catch (IOException ioe) {
                                    AdtPlugin.log(ioe, null);
                                }
                            }
                        } else if (!name.equals("recipe") && !name.equals(TAG_DEPENDENCY)) { //$NON-NLS-1$
                            System.err.println("WARNING: Unknown template directive " + name);
                        }
                    } catch (Exception e) {
                        sMostRecentException = e;
                        AdtPlugin.log(e, null);
                    }
                }
            });

        } catch (Exception e) {
            sMostRecentException = e;
            AdtPlugin.log(e, null);
        }
    }

    @NonNull
    private File getFullPath(@NonNull String fromPath) {
        if (fromPath.startsWith(VALUE_TEMPLATE_DIR)) {
            return new File(getTemplateRootFolder(), RESOURCE_ROOT + File.separator
                    + fromPath.substring(VALUE_TEMPLATE_DIR.length() + 1).replace('/',
                            File.separatorChar));
        }
        return new File(mRootPath, DATA_ROOT + File.separator + fromPath);
    }

    @NonNull
    private IPath getTargetPath(@NonNull String relative) {
        if (relative.indexOf('\\') != -1) {
            relative = relative.replace('\\', '/');
        }
        return new Path(relative);
    }

    @NonNull
    private IFile getTargetFile(@NonNull IPath path) {
        return mProject.getFile(path);
    }

    private void merge(
            @NonNull final Configuration freemarker,
            @NonNull final Map<String, Object> paramMap,
            @NonNull String relativeFrom,
            @NonNull IPath toPath) throws IOException, TemplateException {

        String currentXml = null;

        IFile to = getTargetFile(toPath);
        if (to.exists()) {
            currentXml = AdtPlugin.readFile(to);
        }

        if (currentXml == null) {
            // The target file doesn't exist: don't merge, just copy
            boolean instantiate = relativeFrom.endsWith(DOT_FTL);
            if (instantiate) {
                instantiate(freemarker, paramMap, relativeFrom, toPath);
            } else {
                copyTemplateResource(relativeFrom, toPath);
            }
            return;
        }

        if (!to.getFileExtension().equals(EXT_XML)) {
            throw new RuntimeException("Only XML files can be merged at this point: " + to);
        }

        String xml = null;
        File from = getFullPath(relativeFrom);
        if (relativeFrom.endsWith(DOT_FTL)) {
            // Perform template substitution of the template prior to merging
            mLoader.setTemplateFile(from);
            Template template = freemarker.getTemplate(from.getName());
            Writer out = new StringWriter();
            template.process(paramMap, out);
            out.flush();
            xml = out.toString();
        } else {
            xml = readTemplateTextResource(from);
            if (xml == null) {
                return;
            }
        }

        Document currentDocument = DomUtilities.parseStructuredDocument(currentXml);
        assert currentDocument != null : currentXml;
        Document fragment = DomUtilities.parseStructuredDocument(xml);
        assert fragment != null : xml;

        XmlFormatStyle formatStyle = XmlFormatStyle.MANIFEST;
        boolean modified;
        boolean ok;
        String fileName = to.getName();
        if (fileName.equals(SdkConstants.FN_ANDROID_MANIFEST_XML)) {
            modified = ok = mergeManifest(currentDocument, fragment);
        } else {
            // Merge plain XML files
            String parentFolderName = to.getParent().getName();
            ResourceFolderType folderType = ResourceFolderType.getFolderType(parentFolderName);
            if (folderType != null) {
                formatStyle = EclipseXmlPrettyPrinter.getForFile(toPath);
            } else {
                formatStyle = XmlFormatStyle.FILE;
            }

            modified = mergeResourceFile(currentDocument, fragment, folderType, paramMap);
            ok = true;
        }

        // Finally write out the merged file (formatting etc)
        String contents = null;
        if (ok) {
            if (modified) {
                contents = EclipseXmlPrettyPrinter.prettyPrint(currentDocument,
                        EclipseXmlFormatPreferences.create(), formatStyle, null,
                        currentXml.endsWith("\n")); //$NON-NLS-1$
            }
        } else {
            // Just insert into file along with comment, using the "standard" conflict
            // syntax that many tools and editors recognize.
            String sep = SdkUtils.getLineSeparator();
            contents =
                    "<<<<<<< Original" + sep
                    + currentXml + sep
                    + "=======" + sep
                    + xml
                    + ">>>>>>> Added" + sep;
        }

        if (contents != null) {
            TextFileChange change = new TextFileChange("Merge " + fileName, to);
            MultiTextEdit rootEdit = new MultiTextEdit();
            rootEdit.addChild(new ReplaceEdit(0, currentXml.length(), contents));
            change.setEdit(rootEdit);
            change.setTextType(SdkConstants.EXT_XML);
            mMergeChanges.add(change);
        }
    }

    /** Merges the given resource file contents into the given resource file
     * @param paramMap */
    private static boolean mergeResourceFile(Document currentDocument, Document fragment,
            ResourceFolderType folderType, Map<String, Object> paramMap) {
        boolean modified = false;

        // Copy namespace declarations
        NamedNodeMap attributes = fragment.getDocumentElement().getAttributes();
        if (attributes != null) {
            for (int i = 0, n = attributes.getLength(); i < n; i++) {
                Attr attribute = (Attr) attributes.item(i);
                if (attribute.getName().startsWith(XMLNS_PREFIX)) {
                    currentDocument.getDocumentElement().setAttribute(attribute.getName(),
                            attribute.getValue());
                }
            }
        }

        // For layouts for example, I want to *append* inside the root all the
        // contents of the new file.
        // But for resources for example, I want to combine elements which specify
        // the same name or id attribute.
        // For elements like manifest files we need to insert stuff at the right
        // location in a nested way (activities in the application element etc)
        // but that doesn't happen for the other file types.
        Element root = fragment.getDocumentElement();
        NodeList children = root.getChildNodes();
        List<Node> nodes = new ArrayList<Node>(children.getLength());
        for (int i = children.getLength() - 1; i >= 0; i--) {
            Node child = children.item(i);
            nodes.add(child);
            root.removeChild(child);
        }
        Collections.reverse(nodes);

        root = currentDocument.getDocumentElement();

        if (folderType == ResourceFolderType.VALUES) {
            // Try to merge items of the same name
            Map<String, Node> old = new HashMap<String, Node>();
            NodeList newSiblings = root.getChildNodes();
            for (int i = newSiblings.getLength() - 1; i >= 0; i--) {
                Node child = newSiblings.item(i);
                if (child.getNodeType() == Node.ELEMENT_NODE) {
                    Element element = (Element) child;
                    String name = getResourceId(element);
                    if (name != null) {
                        old.put(name, element);
                    }
                }
            }

            for (Node node : nodes) {
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    Element element = (Element) node;
                    String name = getResourceId(element);
                    Node replace = name != null ? old.get(name) : null;
                    if (replace != null) {
                        // There is an existing item with the same id: just replace it
                        // ACTUALLY -- let's NOT change it.
                        // Let's say you've used the activity wizard once, and it
                        // emits some configuration parameter as a resource that
                        // it depends on, say "padding". Then the user goes and
                        // tweaks the padding to some other number.
                        // Now running the wizard a *second* time for some new activity,
                        // we should NOT go and set the value back to the template's
                        // default!
                        //root.replaceChild(node, replace);

                        // ... ON THE OTHER HAND... What if it's a parameter class
                        // (where the template rewrites a common attribute). Here it's
                        // really confusing if the new parameter is not set. This is
                        // really an error in the template, since we shouldn't have conflicts
                        // like that, but we need to do something to help track this down.
                        AdtPlugin.log(null,
                                "Warning: Ignoring name conflict in resource file for name %1$s",
                                name);
                    } else {
                        root.appendChild(node);
                        modified = true;
                    }
                }
            }
        } else {
            // In other file types, such as layouts, just append all the new content
            // at the end.
            for (Node node : nodes) {
                root.appendChild(node);
                modified = true;
            }
        }
        return modified;
    }

    /** Merges the given manifest fragment into the given manifest file */
    private static boolean mergeManifest(Document currentManifest, Document fragment) {
        // TODO change MergerLog.wrapSdkLog by a custom IMergerLog that will create
        // and maintain error markers.

        // Transfer package element from manifest to merged in root; required by
        // manifest merger
        Element fragmentRoot = fragment.getDocumentElement();
        Element manifestRoot = currentManifest.getDocumentElement();
        if (fragmentRoot == null || manifestRoot == null) {
            return false;
        }
        String pkg = fragmentRoot.getAttribute(ATTR_PACKAGE);
        if (pkg == null || pkg.isEmpty()) {
            pkg = manifestRoot.getAttribute(ATTR_PACKAGE);
            if (pkg != null && !pkg.isEmpty()) {
                fragmentRoot.setAttribute(ATTR_PACKAGE, pkg);
            }
        }

        ManifestMerger merger = new ManifestMerger(
                MergerLog.wrapSdkLog(AdtPlugin.getDefault()),
                new AdtManifestMergeCallback()).setExtractPackagePrefix(true);
        return currentManifest != null &&
                fragment != null &&
                merger.process(currentManifest, fragment);
    }

    /**
     * Makes a backup of the given file, if it exists, by renaming it to name~
     * (and removing an old name~ file if it exists)
     */
    private static boolean makeBackup(File file) {
        if (!file.exists()) {
            return true;
        }
        if (file.isDirectory()) {
            return false;
        }

        File backupFile = new File(file.getParentFile(), file.getName() + '~');
        if (backupFile.exists()) {
            backupFile.delete();
        }
        return file.renameTo(backupFile);
    }

    private static String getResourceId(Element element) {
        String name = element.getAttribute(ATTR_NAME);
        if (name == null) {
            name = element.getAttribute(ATTR_ID);
        }

        return name;
    }

    /** Instantiates the given template file into the given output file */
    private void instantiate(
            @NonNull final Configuration freemarker,
            @NonNull final Map<String, Object> paramMap,
            @NonNull String relativeFrom,
            @NonNull IPath to) throws IOException, TemplateException {
        // For now, treat extension-less files as directories... this isn't quite right
        // so I should refine this! Maybe with a unique attribute in the template file?
        boolean isDirectory = relativeFrom.indexOf('.') == -1;
        if (isDirectory) {
            // It's a directory
            copyTemplateResource(relativeFrom, to);
        } else {
            File from = getFullPath(relativeFrom);
            mLoader.setTemplateFile(from);
            Template template = freemarker.getTemplate(from.getName());
            Writer out = new StringWriter(1024);
            template.process(paramMap, out);
            out.flush();
            String contents = out.toString();

            contents = format(mProject, contents, to);
            IFile targetFile = getTargetFile(to);
            TextFileChange change = createNewFileChange(targetFile);
            MultiTextEdit rootEdit = new MultiTextEdit();
            rootEdit.addChild(new InsertEdit(0, contents));
            change.setEdit(rootEdit);
            mTextChanges.add(change);
        }
    }

    private static String format(IProject project, String contents, IPath to) {
        String name = to.lastSegment();
        if (name.endsWith(DOT_XML)) {
            XmlFormatStyle formatStyle = EclipseXmlPrettyPrinter.getForFile(to);
            EclipseXmlFormatPreferences prefs = EclipseXmlFormatPreferences.create();
            return EclipseXmlPrettyPrinter.prettyPrint(contents, prefs, formatStyle, null);
        } else if (name.endsWith(DOT_JAVA)) {
            Map<?, ?> options = null;
            if (project != null && project.isAccessible()) {
                try {
                    IJavaProject javaProject = BaseProjectHelper.getJavaProject(project);
                    if (javaProject != null) {
                        options = javaProject.getOptions(true);
                    }
                } catch (CoreException e) {
                    AdtPlugin.log(e, null);
                }
            }
            if (options == null) {
                options = JavaCore.getOptions();
            }

            CodeFormatter formatter = ToolFactory.createCodeFormatter(options);

            try {
                IDocument doc = new org.eclipse.jface.text.Document();
                // format the file (the meat and potatoes)
                doc.set(contents);
                TextEdit edit = formatter.format(
                        CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS,
                        contents, 0, contents.length(), 0, null);
                if (edit != null) {
                    edit.apply(doc);
                }

                return doc.get();
            } catch (Exception e) {
                AdtPlugin.log(e, null);
            }
        }

        return contents;
    }

    private static TextFileChange createNewFileChange(IFile targetFile) {
        String fileName = targetFile.getName();
        String message;
        if (targetFile.exists()) {
            message = String.format("Replace %1$s", fileName);
        } else {
            message = String.format("Create %1$s", fileName);
        }

        TextFileChange change = new TextFileChange(message, targetFile) {
            @Override
            protected IDocument acquireDocument(IProgressMonitor pm) throws CoreException {
                IDocument document = super.acquireDocument(pm);

                // In our case, we know we *always* use this TextFileChange
                // to *create* files, we're not appending to existing files.
                // However, due to the following bug we can end up with cached
                // contents of previously deleted files that happened to have the
                // same file name:
                //   https://bugs.eclipse.org/bugs/show_bug.cgi?id=390402
                // Therefore, as a workaround, wipe out the cached contents here
                if (document.getLength() > 0) {
                    try {
                        document.replace(0, document.getLength(), "");
                    } catch (BadLocationException e) {
                        // pass
                    }
                }

                return document;
            }
        };
        change.setTextType(fileName.substring(fileName.lastIndexOf('.') + 1));
        return change;
    }

    /**
     * Returns the list of files to open when the template has been created
     *
     * @return the list of files to open
     */
    @NonNull
    public List<String> getFilesToOpen() {
        return mOpen;
    }

    /**
     * Returns the list of actions to perform when the template has been created
     *
     * @return the list of actions to perform
     */
    @NonNull
    public List<Runnable> getFinalizingActions() {
        return mFinalizingActions;
    }

    /** Copy a template resource */
    private final void copyTemplateResource(
            @NonNull String relativeFrom,
            @NonNull IPath output) throws IOException {
        File from = getFullPath(relativeFrom);
        copy(from, output);
    }

    /** Returns true if the given file contains the given bytes */
    private static boolean isIdentical(@Nullable byte[] data, @NonNull IFile dest) {
        assert dest.exists();
        byte[] existing = AdtUtils.readData(dest);
        return Arrays.equals(existing, data);
    }

    /**
     * Copies the given source file into the given destination file (where the
     * source is allowed to be a directory, in which case the whole directory is
     * copied recursively)
     */
    private void copy(File src, IPath path) throws IOException {
        if (src.isDirectory()) {
            File[] children = src.listFiles();
            if (children != null) {
                for (File child : children) {
                    copy(child, path.append(child.getName()));
                }
            }
        } else {
            IResource dest = mProject.getFile(path);
            if (dest.exists() && !(dest instanceof IFile)) {// Don't attempt to overwrite a folder
                assert false : dest.getClass().getName();
            return;
            }
            IFile file = (IFile) dest;
            String targetName = path.lastSegment();
            if (dest instanceof IFile) {
                if (dest.exists() && isIdentical(Files.toByteArray(src), file)) {
                    String label = String.format(
                            "Not overwriting %1$s because the files are identical", targetName);
                    NullChange change = new NullChange(label);
                    change.setEnabled(false);
                    mOtherChanges.add(change);
                    return;
                }
            }

            if (targetName.endsWith(DOT_XML)
                    || targetName.endsWith(DOT_JAVA)
                    || targetName.endsWith(DOT_TXT)
                    || targetName.endsWith(DOT_RS)
                    || targetName.endsWith(DOT_AIDL)
                    || targetName.endsWith(DOT_SVG)) {

                String newFile = Files.toString(src, Charsets.UTF_8);
                newFile = format(mProject, newFile, path);

                TextFileChange addFile = createNewFileChange(file);
                addFile.setEdit(new InsertEdit(0, newFile));
                mTextChanges.add(addFile);
            } else {
                // Write binary file: Need custom change for that
                IPath workspacePath = mProject.getFullPath().append(path);
                mOtherChanges.add(new CreateFileChange(targetName, workspacePath, src));
            }
        }
    }

    /**
     * A custom {@link TemplateLoader} which locates and provides templates
     * within the plugin .jar file
     */
    private static final class MyTemplateLoader implements TemplateLoader {
        private String mPrefix;

        public void setPrefix(String prefix) {
            mPrefix = prefix;
        }

        public void setTemplateFile(File file) {
            setTemplateParent(file.getParentFile());
        }

        public void setTemplateParent(File parent) {
            mPrefix = parent.getPath();
        }

        @Override
        public Reader getReader(Object templateSource, String encoding) throws IOException {
            URL url = (URL) templateSource;
            return new InputStreamReader(url.openStream(), encoding);
        }

        @Override
        public long getLastModified(Object templateSource) {
            return 0;
        }

        @Override
        public Object findTemplateSource(String name) throws IOException {
            String path = mPrefix != null ? mPrefix + '/' + name : name;
            File file = new File(path);
            if (file.exists()) {
                return file.toURI().toURL();
            }
            return null;
        }

        @Override
        public void closeTemplateSource(Object templateSource) throws IOException {
        }
    }

    /**
     * Validates this template to make sure it's supported
     * @param currentMinSdk the minimum SDK in the project, or -1 or 0 if unknown (e.g. codename)
     * @param buildApi the build API, or -1 or 0 if unknown (e.g. codename)
     *
     * @return a status object with the error, or null if there is no problem
     */
    @SuppressWarnings("cast") // In Eclipse 3.6.2 cast below is needed
    @Nullable
    public IStatus validateTemplate(int currentMinSdk, int buildApi) {
        TemplateMetadata template = getTemplate();
        if (template == null) {
            return null;
        }
        if (!template.isSupported()) {
            String versionString = (String) AdtPlugin.getDefault().getBundle().getHeaders().get(
                    Constants.BUNDLE_VERSION);
            Version version = new Version(versionString);
            return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                    String.format("This template requires a more recent version of the " +
                            "Android Eclipse plugin. Please update from version %1$d.%2$d.%3$d.",
                            version.getMajor(), version.getMinor(), version.getMicro()));
        }
        int templateMinSdk = template.getMinSdk();
        if (templateMinSdk > currentMinSdk && currentMinSdk >= 1) {
            return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                    String.format("This template requires a minimum SDK version of at " +
                            "least %1$d, and the current min version is %2$d",
                            templateMinSdk, currentMinSdk));
        }
        int templateMinBuildApi = template.getMinBuildApi();
        if (templateMinBuildApi >  buildApi && buildApi >= 1) {
            return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
                    String.format("This template requires a build target API version of at " +
                            "least %1$d, and the current version is %2$d",
                            templateMinBuildApi, buildApi));
        }

        return null;
    }
}
