/*
 * 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_NS_NAME_PREFIX;
import static com.android.SdkConstants.ANDROID_URI;
import static com.android.SdkConstants.ATTR_HINT;
import static com.android.SdkConstants.ATTR_ID;
import static com.android.SdkConstants.ATTR_LAYOUT_MARGIN;
import static com.android.SdkConstants.ATTR_LAYOUT_RESOURCE_PREFIX;
import static com.android.SdkConstants.ATTR_NAME;
import static com.android.SdkConstants.ATTR_ON_CLICK;
import static com.android.SdkConstants.ATTR_PARENT;
import static com.android.SdkConstants.ATTR_SRC;
import static com.android.SdkConstants.ATTR_STYLE;
import static com.android.SdkConstants.ATTR_TEXT;
import static com.android.SdkConstants.EXT_XML;
import static com.android.SdkConstants.FD_RESOURCES;
import static com.android.SdkConstants.FD_RES_VALUES;
import static com.android.SdkConstants.PREFIX_ANDROID;
import static com.android.SdkConstants.PREFIX_RESOURCE_REF;
import static com.android.SdkConstants.REFERENCE_STYLE;
import static com.android.SdkConstants.TAG_ITEM;
import static com.android.SdkConstants.TAG_RESOURCES;
import static com.android.SdkConstants.XMLNS_PREFIX;
import static com.android.ide.eclipse.adt.AdtConstants.WS_SEP;

import com.android.annotations.NonNull;
import com.android.annotations.VisibleForTesting;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.ide.common.resources.ResourceResolver;
import com.android.ide.common.xml.XmlFormatStyle;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
import com.android.ide.eclipse.adt.internal.wizards.newxmlfile.NewXmlFileWizard;
import com.android.utils.Pair;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
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.Refactoring;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.TextFileChange;
import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.MultiTextEdit;
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.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/**
 * 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.
 * <p>
 * Remaining work to do / Possible enhancements:
 * <ul>
 * <li>Optionally look in other files in the project and attempt to set style attributes
 * in other cases where the style attributes match?
 * <li>If the elements we are extracting from already contain a style attribute, set that
 * style as the parent style of the current style?
 * <li>Add a parent-style picker to the wizard (initialized with the above if applicable)
 * <li>Pick up indentation settings from the XML module
 * <li>Integrate with themes somehow -- make an option to have the extracted style go into
 *    the theme instead
 * </ul>
 */
@SuppressWarnings("restriction") // XML model
public class ExtractStyleRefactoring extends VisualRefactoring {
    private static final String KEY_NAME = "name";                        //$NON-NLS-1$
    private static final String KEY_REMOVE_EXTRACTED = "removeextracted"; //$NON-NLS-1$
    private static final String KEY_REMOVE_ALL = "removeall";             //$NON-NLS-1$
    private static final String KEY_APPLY_STYLE = "applystyle";           //$NON-NLS-1$
    private static final String KEY_PARENT = "parent";           //$NON-NLS-1$
    private String mStyleName;
    /** The name of the file in res/values/ that the style will be added to. Normally
     * res/values/styles.xml - but unit tests pick other names */
    private String mStyleFileName = "styles.xml";
    /** Set a style reference on the extracted elements? */
    private boolean mApplyStyle;
    /** Remove the attributes that were extracted? */
    private boolean mRemoveExtracted;
    /** List of attributes chosen by the user to be extracted */
    private List<Attr> mChosenAttributes = new ArrayList<Attr>();
    /** Remove all attributes that match the extracted attributes names, regardless of value */
    private boolean mRemoveAll;
    /** The parent style to extend */
    private String mParent;
    /** The full list of available attributes in the refactoring */
    private Map<String, List<Attr>> mAvailableAttributes;

    /**
     * This constructor is solely used by {@link Descriptor},
     * to replay a previous refactoring.
     * @param arguments argument map created by #createArgumentMap.
     */
    ExtractStyleRefactoring(Map<String, String> arguments) {
        super(arguments);
        mStyleName = arguments.get(KEY_NAME);
        mRemoveExtracted = Boolean.parseBoolean(arguments.get(KEY_REMOVE_EXTRACTED));
        mRemoveAll = Boolean.parseBoolean(arguments.get(KEY_REMOVE_ALL));
        mApplyStyle = Boolean.parseBoolean(arguments.get(KEY_APPLY_STYLE));
        mParent = arguments.get(KEY_PARENT);
        if (mParent != null && mParent.length() == 0) {
            mParent = null;
        }
    }

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

    @VisibleForTesting
    ExtractStyleRefactoring(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;
            }

            // 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, mStyleName);
        args.put(KEY_REMOVE_EXTRACTED, Boolean.toString(mRemoveExtracted));
        args.put(KEY_REMOVE_ALL, Boolean.toString(mRemoveAll));
        args.put(KEY_APPLY_STYLE, Boolean.toString(mApplyStyle));
        args.put(KEY_PARENT, mParent != null ? mParent : "");

        return args;
    }

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

    void setStyleName(String styleName) {
        mStyleName = styleName;
    }

    void setStyleFileName(String styleFileName) {
        mStyleFileName = styleFileName;
    }

    void setChosenAttributes(List<Attr> attributes) {
        mChosenAttributes = attributes;
    }

    void setRemoveExtracted(boolean removeExtracted) {
        mRemoveExtracted = removeExtracted;
    }

    void setApplyStyle(boolean applyStyle) {
        mApplyStyle = applyStyle;
    }

    void setRemoveAll(boolean removeAll) {
        mRemoveAll = removeAll;
    }

    void setParent(String parent) {
        mParent = parent;
    }

    // ---- Actual implementation of Extract Style modification computation ----

    /**
     * Returns two items: a map from attribute name to a list of attribute nodes of that
     * name, and a subset of these attributes that fall within the text selection
     * (used to drive initial selection in the wizard)
     */
    Pair<Map<String, List<Attr>>, Set<Attr>> getAvailableAttributes() {
        mAvailableAttributes = new TreeMap<String, List<Attr>>();
        Set<Attr> withinSelection = new HashSet<Attr>();
        for (Element element : getElements()) {
            IndexedRegion elementRegion = getRegion(element);
            boolean allIncluded =
                (mOriginalSelectionStart <= elementRegion.getStartOffset() &&
                 mOriginalSelectionEnd >= elementRegion.getEndOffset());

            NamedNodeMap attributeMap = element.getAttributes();
            for (int i = 0, n = attributeMap.getLength(); i < n; i++) {
                Attr attribute = (Attr) attributeMap.item(i);

                String name = attribute.getLocalName();
                if (!isStylableAttribute(name)) {
                    // Don't offer to extract attributes that don't make sense in
                    // styles (like "id" or "style"), or attributes that the user
                    // probably does not want to define in styles (like layout
                    // attributes such as layout_width, or the label of a button etc).
                    // This makes the options offered listed in the wizard simpler.
                    // In special cases where the user *does* want to set one of these
                    // attributes, they can always do it manually so optimize for
                    // the common case here.
                    continue;
                }

                // Skip attributes that are in a namespace other than the Android one
                String namespace = attribute.getNamespaceURI();
                if (namespace != null && !ANDROID_URI.equals(namespace)) {
                    continue;
                }

                if (!allIncluded) {
                    IndexedRegion region = getRegion(attribute);
                    boolean attributeIncluded = mOriginalSelectionStart < region.getEndOffset() &&
                        mOriginalSelectionEnd >= region.getStartOffset();
                    if (attributeIncluded) {
                        withinSelection.add(attribute);
                    }
                } else {
                    withinSelection.add(attribute);
                }

                List<Attr> list = mAvailableAttributes.get(name);
                if (list == null) {
                    list = new ArrayList<Attr>();
                    mAvailableAttributes.put(name, list);
                }
                list.add(attribute);
            }
        }

        return Pair.of(mAvailableAttributes, withinSelection);
    }

    /**
     * Returns whether the given local attribute name is one the style wizard
     * should present as a selectable attribute to be extracted.
     *
     * @param name the attribute name, not including a namespace prefix
     * @return true if the name is one that the user can extract
     */
    public static boolean isStylableAttribute(String name) {
        return !(name == null
                || name.equals(ATTR_ID)
                || name.startsWith(ATTR_STYLE)
                || (name.startsWith(ATTR_LAYOUT_RESOURCE_PREFIX) &&
                        !name.startsWith(ATTR_LAYOUT_MARGIN))
                || name.equals(ATTR_TEXT)
                || name.equals(ATTR_HINT)
                || name.equals(ATTR_SRC)
                || name.equals(ATTR_ON_CLICK));
    }

    IFile getStyleFile(IProject project) {
        return project.getFile(new Path(FD_RESOURCES + WS_SEP + FD_RES_VALUES + WS_SEP
                + mStyleFileName));
    }

    @Override
    protected @NonNull List<Change> computeChanges(IProgressMonitor monitor) {
        List<Change> changes = new ArrayList<Change>();
        if (mChosenAttributes.size() == 0) {
            return changes;
        }

        IFile file = getStyleFile(mDelegate.getEditor().getProject());
        boolean createFile = !file.exists();
        int insertAtIndex;
        String initialIndent = null;
        if (!createFile) {
            Pair<Integer, String> context = computeInsertContext(file);
            insertAtIndex = context.getFirst();
            initialIndent = context.getSecond();
        } else {
            insertAtIndex = 0;
        }

        TextFileChange addFile = new TextFileChange("Create new separate style declaration", file);
        addFile.setTextType(EXT_XML);
        changes.add(addFile);
        String styleString = computeStyleDeclaration(createFile, initialIndent);
        addFile.setEdit(new InsertEdit(insertAtIndex, styleString));

        // Remove extracted attributes?
        MultiTextEdit rootEdit = new MultiTextEdit();
        if (mRemoveExtracted || mRemoveAll) {
            for (Attr attribute : mChosenAttributes) {
                List<Attr> list = mAvailableAttributes.get(attribute.getLocalName());
                for (Attr attr : list) {
                    if (mRemoveAll || attr.getValue().equals(attribute.getValue())) {
                        removeAttribute(rootEdit, attr);
                    }
                }
            }
        }

        // Set the style attribute?
        if (mApplyStyle) {
            for (Element element : getElements()) {
                String value = PREFIX_RESOURCE_REF + REFERENCE_STYLE + mStyleName;
                setAttribute(rootEdit, element, null, null, ATTR_STYLE, value);
            }
        }

        if (rootEdit.hasChildren()) {
            IFile sourceFile = mDelegate.getEditor().getInputFile();
            if (sourceFile == null) {
                return changes;
            }
            TextFileChange change = new TextFileChange(sourceFile.getName(), sourceFile);
            change.setTextType(EXT_XML);
            changes.add(change);

            if (AdtPrefs.getPrefs().getFormatGuiXml()) {
                MultiTextEdit formatted = reformat(rootEdit, XmlFormatStyle.LAYOUT);
                if (formatted != null) {
                    rootEdit = formatted;
                }
            }

            change.setEdit(rootEdit);
        }

        return changes;
    }

    private String computeStyleDeclaration(boolean createFile, String initialIndent) {
        StringBuilder sb = new StringBuilder();
        if (createFile) {
            sb.append(NewXmlFileWizard.XML_HEADER_LINE);
            sb.append('<').append(TAG_RESOURCES).append(' ');
            sb.append(XMLNS_PREFIX).append(ANDROID_NS_NAME).append('=').append('"');
            sb.append(ANDROID_URI);
            sb.append('"').append('>').append('\n');
        }

        // Indent. Use the existing indent found for previous <style> elements in
        // the resource file - but if that indent was 0 (e.g. <style> elements are
        // at the left margin) only use it to indent the style elements and use a real
        // nonzero indent for its children.
        String indent = "    "; //$NON-NLS-1$
        if (initialIndent == null) {
            initialIndent = indent;
        } else if (initialIndent.length() > 0) {
            indent = initialIndent;
        }
        sb.append(initialIndent);
        String styleTag = "style"; //$NON-NLS-1$ // TODO - use constant in parallel changeset
        sb.append('<').append(styleTag).append(' ').append(ATTR_NAME).append('=').append('"');
        sb.append(mStyleName);
        sb.append('"');
        if (mParent != null) {
            sb.append(' ').append(ATTR_PARENT).append('=').append('"');
            sb.append(mParent);
            sb.append('"');
        }
        sb.append('>').append('\n');

        for (Attr attribute : mChosenAttributes) {
            sb.append(initialIndent).append(indent);
            sb.append('<').append(TAG_ITEM).append(' ').append(ATTR_NAME).append('=').append('"');
            // We've already enforced that regardless of prefix, only attributes with
            // an Android namespace can be in the set of chosen attributes. Rewrite the
            // prefix to android here.
            if (attribute.getPrefix() != null) {
                sb.append(ANDROID_NS_NAME_PREFIX);
            }
            sb.append(attribute.getLocalName());
            sb.append('"').append('>');
            sb.append(attribute.getValue());
            sb.append('<').append('/').append(TAG_ITEM).append('>').append('\n');
        }
        sb.append(initialIndent).append('<').append('/').append(styleTag).append('>').append('\n');

        if (createFile) {
            sb.append('<').append('/').append(TAG_RESOURCES).append('>').append('\n');
        }
        String styleString = sb.toString();
        return styleString;
    }

    /** Computes the location in the file to insert the new style element at, as well as
     * the exact indent string to use to indent the {@code <style>} element.
     * @param file the styles.xml file to insert into
     * @return a pair of an insert offset and an indent string
     */
    private Pair<Integer, String> computeInsertContext(final IFile file) {
        int insertAtIndex = -1;
        // Find the insert of the final </resources> item where we will insert
        // the new style elements.
        String indent = null;
        IModelManager modelManager = StructuredModelManager.getModelManager();
        IStructuredModel model = null;
        try {
            model = modelManager.getModelForRead(file);
            if (model instanceof IDOMModel) {
                IDOMModel domModel = (IDOMModel) model;
                IDOMDocument otherDocument = domModel.getDocument();
                Element root = otherDocument.getDocumentElement();
                Node lastChild = root.getLastChild();
                if (lastChild != null) {
                    if (lastChild instanceof IndexedRegion) {
                        IndexedRegion region = (IndexedRegion) lastChild;
                        insertAtIndex = region.getStartOffset() + region.getLength();
                    }

                    // Compute indent
                    while (lastChild != null) {
                        if (lastChild.getNodeType() == Node.ELEMENT_NODE) {
                            IStructuredDocument document = model.getStructuredDocument();
                            indent = AndroidXmlEditor.getIndent(document, lastChild);
                            break;
                        }
                        lastChild = lastChild.getPreviousSibling();
                    }
                }
            }
        } catch (IOException e) {
            AdtPlugin.log(e, null);
        } catch (CoreException e) {
            AdtPlugin.log(e, null);
        } finally {
            if (model != null) {
                model.releaseFromRead();
            }
        }

        if (insertAtIndex == -1) {
            String contents = AdtPlugin.readFile(file);
            insertAtIndex = contents.indexOf("</" + TAG_RESOURCES + ">"); //$NON-NLS-1$
            if (insertAtIndex == -1) {
                insertAtIndex = contents.length();
            }
        }

        return Pair.of(insertAtIndex, indent);
    }

    @Override
    VisualRefactoringWizard createWizard() {
        return new ExtractStyleWizard(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.style", //$NON-NLS-1$
                    project, description, comment, arguments);
        }

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

    /**
     * Determines the parent style to be used for this refactoring
     *
     * @return the parent style to be used for this refactoring
     */
    public String getParentStyle() {
        Set<String> styles = new HashSet<String>();
        for (Element element : getElements()) {
            // Includes "" for elements not setting the style
            styles.add(element.getAttribute(ATTR_STYLE));
        }

        if (styles.size() > 1) {
            // The elements differ in what style attributes they are set to
            return null;
        }

        String style = styles.iterator().next();
        if (style != null && style.length() > 0) {
            return style;
        }

        // None of the elements set the style -- see if they have the same widget types
        // and if so offer to extend the theme style for that widget type

        Set<String> types = new HashSet<String>();
        for (Element element : getElements()) {
            types.add(element.getTagName());
        }

        if (types.size() == 1) {
            String view = DescriptorsUtils.getBasename(types.iterator().next());

            ResourceResolver resolver = mDelegate.getGraphicalEditor().getResourceResolver();
            // Look up the theme item name, which for a Button would be "buttonStyle", and so on.
            String n = Character.toLowerCase(view.charAt(0)) + view.substring(1)
                + "Style"; //$NON-NLS-1$
            ResourceValue value = resolver.findItemInTheme(n);
            if (value != null) {
                ResourceValue resolvedValue = resolver.resolveResValue(value);
                String name = resolvedValue.getName();
                if (name != null) {
                    if (resolvedValue.isFramework()) {
                        return PREFIX_ANDROID + name;
                    } else {
                        return name;
                    }
                }
            }
        }

        return null;
    }
}
