/*
 * Copyright (C) 2010 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.refactorings.core;

import static com.android.SdkConstants.ANDROID_URI;
import static com.android.SdkConstants.ATTR_CLASS;
import static com.android.SdkConstants.ATTR_CONTEXT;
import static com.android.SdkConstants.ATTR_NAME;
import static com.android.SdkConstants.DOT_XML;
import static com.android.SdkConstants.EXT_XML;
import static com.android.SdkConstants.TOOLS_URI;
import static com.android.SdkConstants.VIEW_FRAGMENT;
import static com.android.SdkConstants.VIEW_TAG;

import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.ide.common.xml.ManifestData;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.resources.ResourceFolderType;
import com.android.utils.SdkUtils;

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.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CompositeChange;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.TextFileChange;
import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
import org.eclipse.ltk.core.refactoring.participants.MoveParticipant;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;
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.text.IStructuredDocument;
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 org.w3c.dom.NodeList;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * A participant to participate in refactorings that move a type in an Android project.
 * The class updates android manifest and the layout file
 * The user can suppress refactoring by disabling the "Update references" checkbox
 * <p>
 * Rename participants are registered via the extension point <code>
 * org.eclipse.ltk.core.refactoring.moveParticipants</code>.
 * Extensions to this extension point must therefore extend <code>org.eclipse.ltk.core.refactoring.participants.MoveParticipant</code>.
 * </p>
 */
@SuppressWarnings("restriction")
public class AndroidTypeMoveParticipant extends MoveParticipant {

    private IProject mProject;
    protected IFile mManifestFile;
    protected String mOldFqcn;
    protected String mNewFqcn;
    protected String mAppPackage;

    @Override
    public String getName() {
        return "Android Type Move";
    }

    @Override
    public RefactoringStatus checkConditions(IProgressMonitor pm, CheckConditionsContext context)
            throws OperationCanceledException {
        return new RefactoringStatus();
    }

    @Override
    protected boolean initialize(Object element) {
        if (element instanceof IType) {
            IType type = (IType) element;
            IJavaProject javaProject = (IJavaProject) type.getAncestor(IJavaElement.JAVA_PROJECT);
            mProject = javaProject.getProject();
            IResource manifestResource = mProject.findMember(AdtConstants.WS_SEP
                    + SdkConstants.FN_ANDROID_MANIFEST_XML);

            if (manifestResource == null || !manifestResource.exists()
                    || !(manifestResource instanceof IFile)) {
                RefactoringUtil.logInfo("Invalid or missing the "
                        + SdkConstants.FN_ANDROID_MANIFEST_XML + " in the " + mProject.getName()
                        + " project.");
                return false;
            }
            mManifestFile = (IFile) manifestResource;
            ManifestData manifestData;
            manifestData = AndroidManifestHelper.parseForData(mManifestFile);
            if (manifestData == null) {
                return false;
            }
            mAppPackage = manifestData.getPackage();
            mOldFqcn = type.getFullyQualifiedName();
            Object destination = getArguments().getDestination();
            if (destination instanceof IPackageFragment) {
                IPackageFragment packageFragment = (IPackageFragment) destination;
                mNewFqcn = packageFragment.getElementName() + "." + type.getElementName();
            } else if (destination instanceof IResource) {
                try {
                    IPackageFragment[] fragments = javaProject.getPackageFragments();
                    for (IPackageFragment fragment : fragments) {
                        IResource resource = fragment.getResource();
                        if (resource.equals(destination)) {
                            mNewFqcn = fragment.getElementName() + '.' + type.getElementName();
                            break;
                        }
                    }
                } catch (JavaModelException e) {
                    // pass
                }
            }
            return mOldFqcn != null && mNewFqcn != null;
        }

        return false;
    }

    @Override
    public Change createChange(IProgressMonitor pm) throws CoreException,
            OperationCanceledException {
        if (pm.isCanceled()) {
            return null;
        }
        if (!getArguments().getUpdateReferences()) {
            return null;
        }
        CompositeChange result = new CompositeChange(getName());
        result.markAsSynthetic();

        addManifestFileChanges(result);

        // Update layout files; we don't just need to react to custom view
        // changes, we need to update fragment references and even tool:context activity
        // references
        addLayoutFileChanges(mProject, result);

        // Also update in dependent projects
        ProjectState projectState = Sdk.getProjectState(mProject);
        if (projectState != null) {
            Collection<ProjectState> parentProjects = projectState.getFullParentProjects();
            for (ProjectState parentProject : parentProjects) {
                IProject project = parentProject.getProject();
                addLayoutFileChanges(project, result);
            }
        }

        return (result.getChildren().length == 0) ? null : result;
    }

    private void addManifestFileChanges(CompositeChange result) {
        addXmlFileChanges(mManifestFile, result, true);
    }

    private void addLayoutFileChanges(IProject project, CompositeChange result) {
        try {
            // Update references in XML resource files
            IFolder resFolder = project.getFolder(SdkConstants.FD_RESOURCES);

            IResource[] folders = resFolder.members();
            for (IResource folder : folders) {
                String folderName = folder.getName();
                ResourceFolderType folderType = ResourceFolderType.getFolderType(folderName);
                if (folderType != ResourceFolderType.LAYOUT) {
                    continue;
                }
                if (!(folder instanceof IFolder)) {
                    continue;
                }
                IResource[] files = ((IFolder) folder).members();
                for (int i = 0; i < files.length; i++) {
                    IResource member = files[i];
                    if ((member instanceof IFile) && member.exists()) {
                        IFile file = (IFile) member;
                        String fileName = member.getName();

                        if (SdkUtils.endsWith(fileName, DOT_XML)) {
                            addXmlFileChanges(file, result, false);
                        }
                    }
                }
            }
        } catch (CoreException e) {
            RefactoringUtil.log(e);
        }
    }

    private boolean addXmlFileChanges(IFile file, CompositeChange changes, boolean isManifest) {
        IModelManager modelManager = StructuredModelManager.getModelManager();
        IStructuredModel model = null;
        try {
            model = modelManager.getExistingModelForRead(file);
            if (model == null) {
                model = modelManager.getModelForRead(file);
            }
            if (model != null) {
                IStructuredDocument document = model.getStructuredDocument();
                if (model instanceof IDOMModel) {
                    IDOMModel domModel = (IDOMModel) model;
                    Element root = domModel.getDocument().getDocumentElement();
                    if (root != null) {
                        List<TextEdit> edits = new ArrayList<TextEdit>();
                        if (isManifest) {
                            addManifestReplacements(edits, root, document);
                        } else {
                            addLayoutReplacements(edits, root, document);
                        }
                        if (!edits.isEmpty()) {
                            MultiTextEdit rootEdit = new MultiTextEdit();
                            rootEdit.addChildren(edits.toArray(new TextEdit[edits.size()]));
                            TextFileChange change = new TextFileChange(file.getName(), file);
                            change.setTextType(EXT_XML);
                            change.setEdit(rootEdit);
                            changes.add(change);
                        }
                    }
                } else {
                    return false;
                }
            }

            return true;
        } catch (IOException e) {
            AdtPlugin.log(e, null);
        } catch (CoreException e) {
            AdtPlugin.log(e, null);
        } finally {
            if (model != null) {
                model.releaseFromRead();
            }
        }

        return false;
    }

    private void addLayoutReplacements(
            @NonNull List<TextEdit> edits,
            @NonNull Element element,
            @NonNull IStructuredDocument document) {
        String tag = element.getTagName();
        if (tag.equals(mOldFqcn)) {
            int start = RefactoringUtil.getTagNameRangeStart(element, document);
            if (start != -1) {
                int end = start + mOldFqcn.length();
                edits.add(new ReplaceEdit(start, end - start, mNewFqcn));
            }
        } else if (tag.equals(VIEW_TAG)) {
            Attr classNode = element.getAttributeNode(ATTR_CLASS);
            if (classNode != null && classNode.getValue().equals(mOldFqcn)) {
                int start = RefactoringUtil.getAttributeValueRangeStart(classNode, document);
                if (start != -1) {
                    int end = start + mOldFqcn.length();
                    edits.add(new ReplaceEdit(start, end - start, mNewFqcn));
                }
            }
        } else if (tag.equals(VIEW_FRAGMENT)) {
            Attr classNode = element.getAttributeNode(ATTR_CLASS);
            if (classNode == null) {
                classNode = element.getAttributeNodeNS(ANDROID_URI, ATTR_NAME);
            }
            if (classNode != null && classNode.getValue().equals(mOldFqcn)) {
                int start = RefactoringUtil.getAttributeValueRangeStart(classNode, document);
                if (start != -1) {
                    int end = start + mOldFqcn.length();
                    edits.add(new ReplaceEdit(start, end - start, mNewFqcn));
                }
            }
        } else if (element.hasAttributeNS(TOOLS_URI, ATTR_CONTEXT)) {
            Attr classNode = element.getAttributeNodeNS(TOOLS_URI, ATTR_CONTEXT);
            if (classNode != null && classNode.getValue().equals(mOldFqcn)) {
                int start = RefactoringUtil.getAttributeValueRangeStart(classNode, document);
                if (start != -1) {
                    int end = start + mOldFqcn.length();
                    edits.add(new ReplaceEdit(start, end - start, mNewFqcn));
                }
            }
        }

        NodeList children = element.getChildNodes();
        for (int i = 0, n = children.getLength(); i < n; i++) {
            Node child = children.item(i);
            if (child.getNodeType() == Node.ELEMENT_NODE) {
                addLayoutReplacements(edits, (Element) child, document);
            }
        }
    }

    private void addManifestReplacements(
            @NonNull List<TextEdit> edits,
            @NonNull Element element,
            @NonNull IStructuredDocument document) {
        NamedNodeMap attributes = element.getAttributes();
        for (int i = 0, n = attributes.getLength(); i < n; i++) {
            Attr attr = (Attr) attributes.item(i);
            if (!RefactoringUtil.isManifestClassAttribute(attr)) {
                continue;
            }

            String value = attr.getValue();
            if (value.equals(mOldFqcn)) {
                int start = RefactoringUtil.getAttributeValueRangeStart(attr, document);
                if (start != -1) {
                    int end = start + mOldFqcn.length();
                    edits.add(new ReplaceEdit(start, end - start, mNewFqcn));
                }
            } else if (value.startsWith(".")) { //$NON-NLS-1$
                String fqcn = mAppPackage + value;
                if (fqcn.equals(mOldFqcn)) {
                    int start = RefactoringUtil.getAttributeValueRangeStart(attr, document);
                    if (start != -1) {
                        int end = start + value.length();
                        edits.add(new ReplaceEdit(start, end - start, mNewFqcn));
                    }
                }
            }
        }

        NodeList children = element.getChildNodes();
        for (int i = 0, n = children.getLength(); i < n; i++) {
            Node child = children.item(i);
            if (child.getNodeType() == Node.ELEMENT_NODE) {
                addManifestReplacements(edits, (Element) child, document);
            }
        }
    }
}
