/*
 * 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.editors.layout.refactoring;

import static com.android.SdkConstants.ANDROID_NS_NAME;
import static com.android.SdkConstants.ANDROID_URI;
import static com.android.SdkConstants.ATTR_ID;
import static com.android.SdkConstants.ATTR_LAYOUT_HEIGHT;
import static com.android.SdkConstants.ATTR_LAYOUT_RESOURCE_PREFIX;
import static com.android.SdkConstants.ATTR_LAYOUT_WIDTH;
import static com.android.SdkConstants.DOT_XML;
import static com.android.SdkConstants.EXT_XML;
import static com.android.SdkConstants.FD_RES;
import static com.android.SdkConstants.FD_RESOURCES;
import static com.android.SdkConstants.FD_RES_LAYOUT;
import static com.android.SdkConstants.ID_PREFIX;
import static com.android.SdkConstants.NEW_ID_PREFIX;
import static com.android.SdkConstants.VALUE_WRAP_CONTENT;
import static com.android.SdkConstants.VIEW_INCLUDE;
import static com.android.SdkConstants.XMLNS;
import static com.android.SdkConstants.XMLNS_PREFIX;
import static com.android.ide.eclipse.adt.AdtConstants.WS_SEP;
import static com.android.resources.ResourceType.LAYOUT;

import com.android.annotations.NonNull;
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.internal.editors.formatting.EclipseXmlFormatPreferences;
import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlPrettyPrinter;
import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.CanvasViewInfo;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.DomUtilities;
import com.android.ide.eclipse.adt.internal.editors.layout.uimodel.UiViewElementNode;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
import com.android.ide.eclipse.adt.internal.resources.ResourceNameValidator;
import com.android.utils.XmlUtils;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
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.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.NullChange;
import org.eclipse.ltk.core.refactoring.Refactoring;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.TextFileChange;
import org.eclipse.swt.widgets.Display;
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.eclipse.ui.IWorkbenchPage;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
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 java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * Extracts the selection and writes it out as a separate layout file, then adds an
 * include to that new layout file. Interactively asks the user for a new name for the
 * layout.
 */
@SuppressWarnings("restriction") // XML model
public class ExtractIncludeRefactoring extends VisualRefactoring {
    private static final String KEY_NAME = "name";                      //$NON-NLS-1$
    private static final String KEY_OCCURRENCES = "all-occurrences";    //$NON-NLS-1$
    private String mLayoutName;
    private boolean mReplaceOccurrences;

    /**
     * This constructor is solely used by {@link Descriptor},
     * to replay a previous refactoring.
     * @param arguments argument map created by #createArgumentMap.
     */
    ExtractIncludeRefactoring(Map<String, String> arguments) {
        super(arguments);
        mLayoutName = arguments.get(KEY_NAME);
        mReplaceOccurrences  = Boolean.parseBoolean(arguments.get(KEY_OCCURRENCES));
    }

    public ExtractIncludeRefactoring(
            IFile file,
            LayoutEditorDelegate delegate,
            ITextSelection selection,
            ITreeSelection treeSelection) {
        super(file, delegate, selection, treeSelection);
    }

    @VisibleForTesting
    ExtractIncludeRefactoring(List<Element> selectedElements, LayoutEditorDelegate editor) {
        super(selectedElements, editor);
    }

    @Override
    public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException,
            OperationCanceledException {
        RefactoringStatus status = new RefactoringStatus();

        try {
            pm.beginTask("Checking preconditions...", 6);

            if (mSelectionStart == -1 || mSelectionEnd == -1) {
                status.addFatalError("No selection to extract");
                return status;
            }

            // Make sure the selection is contiguous
            if (mTreeSelection != null) {
                // TODO - don't do this if we based the selection on text. In this case,
                // make sure we're -balanced-.
                List<CanvasViewInfo> infos = getSelectedViewInfos();
                if (!validateNotEmpty(infos, status)) {
                    return status;
                }

                if (!validateNotRoot(infos, status)) {
                    return status;
                }

                // Disable if you've selected a single include tag
                if (infos.size() == 1) {
                    UiViewElementNode uiNode = infos.get(0).getUiViewNode();
                    if (uiNode != null) {
                        Node xmlNode = uiNode.getXmlNode();
                        if (xmlNode.getLocalName().equals(VIEW_INCLUDE)) {
                            status.addWarning("No point in refactoring a single include tag");
                        }
                    }
                }

                // Enforce that the selection is -contiguous-
                if (!validateContiguous(infos, status)) {
                    return status;
                }
            }

            // This also ensures that we have a valid DOM model:
            if (mElements.size() == 0) {
                status.addFatalError("Nothing to extract");
                return status;
            }

            pm.worked(1);
            return status;

        } finally {
            pm.done();
        }
    }

    @Override
    protected VisualRefactoringDescriptor createDescriptor() {
        String comment = getName();
        return new Descriptor(
                mProject.getName(), //project
                comment, //description
                comment, //comment
                createArgumentMap());
    }

    @Override
    protected Map<String, String> createArgumentMap() {
        Map<String, String> args = super.createArgumentMap();
        args.put(KEY_NAME, mLayoutName);
        args.put(KEY_OCCURRENCES, Boolean.toString(mReplaceOccurrences));

        return args;
    }

    @Override
    public String getName() {
        return "Extract as Include";
    }

    void setLayoutName(String layoutName) {
        mLayoutName = layoutName;
    }

    void setReplaceOccurrences(boolean selection) {
        mReplaceOccurrences = selection;
    }

    // ---- Actual implementation of Extract as Include modification computation ----

    @Override
    protected @NonNull List<Change> computeChanges(IProgressMonitor monitor) {
        String extractedText = getExtractedText();

        String namespaceDeclarations = computeNamespaceDeclarations();

        // Insert namespace:
        extractedText = insertNamespace(extractedText, namespaceDeclarations);

        StringBuilder sb = new StringBuilder();
        sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); //$NON-NLS-1$
        sb.append(extractedText);
        sb.append('\n');

        List<Change> changes = new ArrayList<Change>();

        String newFileName = mLayoutName + DOT_XML;
        IProject project = mDelegate.getEditor().getProject();
        IFile sourceFile = mDelegate.getEditor().getInputFile();
        if (sourceFile == null) {
            return changes;
        }

        // Replace extracted elements by <include> tag
        handleIncludingFile(changes, sourceFile, mSelectionStart, mSelectionEnd,
                getDomDocument(), getPrimaryElement());

        // Also extract in other variations of the same file (landscape/portrait, etc)
        boolean haveVariations = false;
        if (mReplaceOccurrences) {
            List<IFile> layouts = getOtherLayouts(sourceFile);
            for (IFile file : layouts) {
                IModelManager modelManager = StructuredModelManager.getModelManager();
                IStructuredModel model = null;
                // We could enhance this with a SubMonitor to make the progress bar move as
                // well.
                monitor.subTask(String.format("Looking for duplicates in %1$s",
                        file.getProjectRelativePath()));
                if (monitor.isCanceled()) {
                    throw new OperationCanceledException();
                }

                try {
                    model = modelManager.getModelForRead(file);
                    if (model instanceof IDOMModel) {
                        IDOMModel domModel = (IDOMModel) model;
                        IDOMDocument otherDocument = domModel.getDocument();
                        List<Element> otherElements = new ArrayList<Element>();
                        Element otherPrimary = null;

                        for (Element element : getElements()) {
                            Element other = DomUtilities.findCorresponding(element,
                                    otherDocument);
                            if (other != null) {
                                // See if the structure is similar to what we have in this
                                // document
                                if (DomUtilities.isEquivalent(element, other)) {
                                    otherElements.add(other);
                                    if (element == getPrimaryElement()) {
                                        otherPrimary = other;
                                    }
                                }
                            }
                        }

                        // Only perform extract in the other file if we find a match for
                        // ALL of elements being extracted, and if they too are contiguous
                        if (otherElements.size() == getElements().size() &&
                                DomUtilities.isContiguous(otherElements)) {
                            // Find the range
                            int begin = Integer.MAX_VALUE;
                            int end = Integer.MIN_VALUE;
                            for (Element element : otherElements) {
                                // Yes!! Extract this one as well!
                                IndexedRegion region = getRegion(element);
                                end = Math.max(end, region.getEndOffset());
                                begin = Math.min(begin, region.getStartOffset());
                            }
                            handleIncludingFile(changes, file, begin,
                                    end, otherDocument, otherPrimary);
                            haveVariations = true;
                        }
                    }
                } catch (IOException e) {
                    AdtPlugin.log(e, null);
                } catch (CoreException e) {
                    AdtPlugin.log(e, null);
                } finally {
                    if (model != null) {
                        model.releaseFromRead();
                    }
                }
            }
        }

        // Add change to create the new file
        IContainer parent = sourceFile.getParent();
        if (haveVariations) {
            // If we're extracting from multiple configuration folders, then we need to
            // place the extracted include in the base layout folder (if not it goes next to
            // the including file)
            parent = mProject.getFolder(FD_RES).getFolder(FD_RES_LAYOUT);
        }
        IPath parentPath = parent.getProjectRelativePath();
        final IFile file = project.getFile(new Path(parentPath + WS_SEP + newFileName));
        TextFileChange addFile = new TextFileChange("Create new separate layout", file);
        addFile.setTextType(EXT_XML);
        changes.add(addFile);

        String newFile = sb.toString();
        if (AdtPrefs.getPrefs().getFormatGuiXml()) {
            newFile = EclipseXmlPrettyPrinter.prettyPrint(newFile,
                    EclipseXmlFormatPreferences.create(), XmlFormatStyle.LAYOUT,
                    null /*lineSeparator*/);
        }
        addFile.setEdit(new InsertEdit(0, newFile));

        Change finishHook = createFinishHook(file);
        changes.add(finishHook);

        return changes;
    }

    private void handleIncludingFile(List<Change> changes,
            IFile sourceFile, int begin, int end, Document document, Element primary) {
        TextFileChange change = new TextFileChange(sourceFile.getName(), sourceFile);
        MultiTextEdit rootEdit = new MultiTextEdit();
        change.setTextType(EXT_XML);
        changes.add(change);

        String referenceId = getReferenceId();
        // Replace existing elements in the source file and insert <include>
        String androidNsPrefix = getAndroidNamespacePrefix(document);
        String include = computeIncludeString(primary, mLayoutName, androidNsPrefix, referenceId);
        int length = end - begin;
        ReplaceEdit replace = new ReplaceEdit(begin, length, include);
        rootEdit.addChild(replace);

        // Update any layout references to the old id with the new id
        if (referenceId != null && primary != null) {
            String rootId = getId(primary);
            IStructuredModel model = null;
            try {
                model = StructuredModelManager.getModelManager().getModelForRead(sourceFile);
                IStructuredDocument doc = model.getStructuredDocument();
                if (doc != null && rootId != null) {
                    List<TextEdit> replaceIds = replaceIds(androidNsPrefix, doc, begin,
                            end, rootId, referenceId);
                    for (TextEdit edit : replaceIds) {
                        rootEdit.addChild(edit);
                    }

                    if (AdtPrefs.getPrefs().getFormatGuiXml()) {
                        MultiTextEdit formatted = reformat(doc.get(), rootEdit,
                                XmlFormatStyle.LAYOUT);
                        if (formatted != null) {
                            rootEdit = formatted;
                        }
                    }
                }
            } catch (IOException e) {
                AdtPlugin.log(e, null);
            } catch (CoreException e) {
                AdtPlugin.log(e, null);
            } finally {
                if (model != null) {
                    model.releaseFromRead();
                }
            }
        }

        change.setEdit(rootEdit);
    }

    /**
     * Returns a list of all the other layouts (in all configurations) in the project other
     * than the given source layout where the refactoring was initiated. Never null.
     */
    private List<IFile> getOtherLayouts(IFile sourceFile) {
        List<IFile> layouts = new ArrayList<IFile>(100);
        IPath sourcePath = sourceFile.getProjectRelativePath();
        IFolder resources = mProject.getFolder(FD_RESOURCES);
        try {
            for (IResource folder : resources.members()) {
                if (folder.getName().startsWith(FD_RES_LAYOUT) &&
                        folder instanceof IFolder) {
                    IFolder layoutFolder = (IFolder) folder;
                    for (IResource file : layoutFolder.members()) {
                        if (file.getName().endsWith(EXT_XML)
                                && file instanceof IFile) {
                            if (!file.getProjectRelativePath().equals(sourcePath)) {
                                layouts.add((IFile) file);
                            }
                        }
                    }
                }
            }
        } catch (CoreException e) {
            AdtPlugin.log(e, null);
        }

        return layouts;
    }

    String getInitialName() {
        String defaultName = ""; //$NON-NLS-1$
        Element primary = getPrimaryElement();
        if (primary != null) {
            String id = primary.getAttributeNS(ANDROID_URI, ATTR_ID);
            // id null check for https://bugs.eclipse.org/bugs/show_bug.cgi?id=272378
            if (id != null && (id.startsWith(ID_PREFIX) || id.startsWith(NEW_ID_PREFIX))) {
                // Use everything following the id/, and make it lowercase since that is
                // the convention for layouts (and use Locale.US to ensure that "Image" becomes
                // "image" etc)
                defaultName = id.substring(id.indexOf('/') + 1).toLowerCase(Locale.US);

                IInputValidator validator = ResourceNameValidator.create(true, mProject, LAYOUT);

                if (validator.isValid(defaultName) != null) { // Already exists?
                    defaultName = ""; //$NON-NLS-1$
                }
            }
        }

        return defaultName;
    }

    IFile getSourceFile() {
        return mFile;
    }

    private Change createFinishHook(final IFile file) {
        return new NullChange("Open extracted layout and refresh resources") {
            @Override
            public Change perform(IProgressMonitor pm) throws CoreException {
                Display display = AdtPlugin.getDisplay();
                display.asyncExec(new Runnable() {
                    @Override
                    public void run() {
                        openFile(file);
                        mDelegate.getGraphicalEditor().refreshProjectResources();
                        // Save file to trigger include finder scanning (as well as making
                        // the
                        // actual show-include feature work since it relies on reading
                        // files from
                        // disk, not a live buffer)
                        IWorkbenchPage page = mDelegate.getEditor().getEditorSite().getPage();
                        page.saveEditor(mDelegate.getEditor(), false);
                    }
                });

                // Not undoable: just return null instead of an undo-change.
                return null;
            }
        };
    }

    private String computeNamespaceDeclarations() {
        String androidNsPrefix = null;
        String namespaceDeclarations = null;

        StringBuilder sb = new StringBuilder();
        List<Attr> attributeNodes = findNamespaceAttributes();
        for (Node attributeNode : attributeNodes) {
            String prefix = attributeNode.getPrefix();
            if (XMLNS.equals(prefix)) {
                sb.append(' ');
                String name = attributeNode.getNodeName();
                sb.append(name);
                sb.append('=').append('"');

                String value = attributeNode.getNodeValue();
                if (value.equals(ANDROID_URI)) {
                    androidNsPrefix = name;
                    if (androidNsPrefix.startsWith(XMLNS_PREFIX)) {
                        androidNsPrefix = androidNsPrefix.substring(XMLNS_PREFIX.length());
                    }
                }
                sb.append(XmlUtils.toXmlAttributeValue(value));
                sb.append('"');
            }
        }
        namespaceDeclarations = sb.toString();

        if (androidNsPrefix == null) {
            androidNsPrefix = ANDROID_NS_NAME;
        }

        if (namespaceDeclarations.length() == 0) {
            sb.setLength(0);
            sb.append(' ');
            sb.append(XMLNS_PREFIX);
            sb.append(androidNsPrefix);
            sb.append('=').append('"');
            sb.append(ANDROID_URI);
            sb.append('"');
            namespaceDeclarations = sb.toString();
        }

        return namespaceDeclarations;
    }

    /** Returns the id to be used for the include tag itself (may be null) */
    private String getReferenceId() {
        String rootId = getRootId();
        if (rootId != null) {
            return rootId + "_ref";
        }

        return null;
    }

    /**
     * Compute the actual {@code <include>} string to be inserted in place of the old
     * selection
     */
    private static String computeIncludeString(Element primaryNode, String newName,
            String androidNsPrefix, String referenceId) {
        StringBuilder sb = new StringBuilder();
        sb.append("<include layout=\"@layout/"); //$NON-NLS-1$
        sb.append(newName);
        sb.append('"');
        sb.append(' ');

        // Create new id for the include itself
        if (referenceId != null) {
            sb.append(androidNsPrefix);
            sb.append(':');
            sb.append(ATTR_ID);
            sb.append('=').append('"');
            sb.append(referenceId);
            sb.append('"').append(' ');
        }

        // Add id string, unless it's a <merge>, since we may need to adjust any layout
        // references to apply to the <include> tag instead

        // I should move all the layout_ attributes as well
        // I also need to duplicate and modify the id and then replace
        // everything else in the file with this new id...

        // HACK: see issue 13494: We must duplicate the width/height attributes on the
        // <include> statement for designtime rendering only
        String width = null;
        String height = null;
        if (primaryNode == null) {
            // Multiple selection - in that case we will be creating an outer <merge>
            // so we need to set our own width/height on it
            width = height = VALUE_WRAP_CONTENT;
        } else {
            if (!primaryNode.hasAttributeNS(ANDROID_URI, ATTR_LAYOUT_WIDTH)) {
                width = VALUE_WRAP_CONTENT;
            } else {
                width = primaryNode.getAttributeNS(ANDROID_URI, ATTR_LAYOUT_WIDTH);
            }
            if (!primaryNode.hasAttributeNS(ANDROID_URI, ATTR_LAYOUT_HEIGHT)) {
                height = VALUE_WRAP_CONTENT;
            } else {
                height = primaryNode.getAttributeNS(ANDROID_URI, ATTR_LAYOUT_HEIGHT);
            }
        }
        if (width != null) {
            sb.append(' ');
            sb.append(androidNsPrefix);
            sb.append(':');
            sb.append(ATTR_LAYOUT_WIDTH);
            sb.append('=').append('"');
            sb.append(XmlUtils.toXmlAttributeValue(width));
            sb.append('"');
        }
        if (height != null) {
            sb.append(' ');
            sb.append(androidNsPrefix);
            sb.append(':');
            sb.append(ATTR_LAYOUT_HEIGHT);
            sb.append('=').append('"');
            sb.append(XmlUtils.toXmlAttributeValue(height));
            sb.append('"');
        }

        // Duplicate all the other layout attributes as well
        if (primaryNode != null) {
            NamedNodeMap attributes = primaryNode.getAttributes();
            for (int i = 0, n = attributes.getLength(); i < n; i++) {
                Node attr = attributes.item(i);
                String name = attr.getLocalName();
                if (name.startsWith(ATTR_LAYOUT_RESOURCE_PREFIX)
                        && ANDROID_URI.equals(attr.getNamespaceURI())) {
                    if (name.equals(ATTR_LAYOUT_WIDTH) || name.equals(ATTR_LAYOUT_HEIGHT)) {
                        // Already handled
                        continue;
                    }

                    sb.append(' ');
                    sb.append(androidNsPrefix);
                    sb.append(':');
                    sb.append(name);
                    sb.append('=').append('"');
                    sb.append(XmlUtils.toXmlAttributeValue(attr.getNodeValue()));
                    sb.append('"');
                }
            }
        }

        sb.append("/>");
        return sb.toString();
    }

    /** Return the text in the document in the range start to end */
    private String getExtractedText() {
        String xml = getText(mSelectionStart, mSelectionEnd);
        Element primaryNode = getPrimaryElement();
        xml = stripTopLayoutAttributes(primaryNode, mSelectionStart, xml);
        xml = dedent(xml);

        // Wrap siblings in <merge>?
        if (primaryNode == null) {
            StringBuilder sb = new StringBuilder();
            sb.append("<merge>\n"); //$NON-NLS-1$
            // indent an extra level
            for (String line : xml.split("\n")) { //$NON-NLS-1$
                sb.append("    "); //$NON-NLS-1$
                sb.append(line).append('\n');
            }
            sb.append("</merge>\n"); //$NON-NLS-1$
            xml = sb.toString();
        }

        return xml;
    }

    @Override
    VisualRefactoringWizard createWizard() {
        return new ExtractIncludeWizard(this, mDelegate);
    }

    public static class Descriptor extends VisualRefactoringDescriptor {
        public Descriptor(String project, String description, String comment,
                Map<String, String> arguments) {
            super("com.android.ide.eclipse.adt.refactoring.extract.include", //$NON-NLS-1$
                    project, description, comment, arguments);
        }

        @Override
        protected Refactoring createRefactoring(Map<String, String> args) {
            return new ExtractIncludeRefactoring(args);
        }
    }
}
