/*
 * 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_MANIFEST_XML;
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.CLASS_VIEW;
import static com.android.SdkConstants.DOT_XML;
import static com.android.SdkConstants.EXT_XML;
import static com.android.SdkConstants.R_CLASS;
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.editors.layout.gle2.DomUtilities;
import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestInfo;
import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
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.resources.ResourceType;
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.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.internal.corext.refactoring.rename.RenameCompilationUnitProcessor;
import org.eclipse.jdt.internal.corext.refactoring.rename.RenameTypeProcessor;
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.RefactoringProcessor;
import org.eclipse.ltk.core.refactoring.participants.RenameParticipant;
import org.eclipse.ltk.core.refactoring.participants.RenameRefactoring;
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 rename 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.renameParticipants</code>.
 * Extensions to this extension point must therefore extend
 * <code>org.eclipse.ltk.core.refactoring.participants.RenameParticipant</code>.
 */
@SuppressWarnings("restriction")
public class AndroidTypeRenameParticipant extends RenameParticipant {
    private IProject mProject;
    private IFile mManifestFile;
    private String mOldFqcn;
    private String mNewFqcn;
    private String mOldSimpleName;
    private String mNewSimpleName;
    private String mOldDottedName;
    private String mNewDottedName;
    private boolean mIsCustomView;

    /**
     * Set while we are creating an embedded Java refactoring. This could cause a recursive
     * invocation of the XML renaming refactoring to react to the field, so this is flag
     * during the call to the Java processor, and is used to ignore requests for adding in
     * field reactions during that time.
     */
    private static boolean sIgnore;

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

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

    @Override
    protected boolean initialize(Object element) {
        if (sIgnore) {
            return false;
        }

        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(
                        String.format("Invalid or missing file %1$s in project %2$s",
                                SdkConstants.FN_ANDROID_MANIFEST_XML,
                                mProject.getName()));
                return false;
            }

            try {
                IType classView = javaProject.findType(CLASS_VIEW);
                if (classView != null) {
                    ITypeHierarchy hierarchy = type.newSupertypeHierarchy(new NullProgressMonitor());
                    if (hierarchy.contains(classView)) {
                        mIsCustomView = true;
                    }
                }
            } catch (CoreException e) {
                AdtPlugin.log(e, null);
            }

            mManifestFile = (IFile) manifestResource;
            ManifestData manifestData;
            manifestData = AndroidManifestHelper.parseForData(mManifestFile);
            if (manifestData == null) {
                return false;
            }
            mOldSimpleName = type.getElementName();
            mOldDottedName = '.' + mOldSimpleName;
            mOldFqcn = type.getFullyQualifiedName();
            String packageName = type.getPackageFragment().getElementName();
            mNewSimpleName = getArguments().getNewName();
            mNewDottedName = '.' + mNewSimpleName;
            if (packageName != null) {
                mNewFqcn = packageName + mNewDottedName;
            } else {
                mNewFqcn = mNewSimpleName;
            }
            if (mOldFqcn == null || mNewFqcn == null) {
                return false;
            }
            if (!RefactoringUtil.isRefactorAppPackage() && mNewFqcn.indexOf('.') == -1) {
                mNewFqcn = packageName + mNewDottedName;
            }
            return true;
        }
        return false;
    }

    @Override
    public Change createChange(IProgressMonitor pm) throws CoreException,
            OperationCanceledException {
        if (pm.isCanceled()) {
            return null;
        }

        // Only propose this refactoring if the "Update References" checkbox is set.
        if (!getArguments().getUpdateReferences()) {
            return null;
        }

        RefactoringProcessor p = getProcessor();
        if (p instanceof RenameCompilationUnitProcessor) {
            RenameTypeProcessor rtp =
                    ((RenameCompilationUnitProcessor) p).getRenameTypeProcessor();
            if (rtp != null) {
                String pattern = rtp.getFilePatterns();
                boolean updQualf = rtp.getUpdateQualifiedNames();
                if (updQualf && pattern != null && pattern.contains("xml")) { //$NON-NLS-1$
                    // Do not propose this refactoring if the
                    // "Update fully qualified names in non-Java files" option is
                    // checked and the file patterns mention XML. [c.f. SDK bug 21589]
                    return null;
                }
            }
        }

        CompositeChange result = new CompositeChange(getName());

        // Only show the children in the refactoring preview dialog
        result.markAsSynthetic();

        addManifestFileChanges(mManifestFile, result);
        addLayoutFileChanges(mProject, result);
        addJavaChanges(mProject, result, pm);

        // Also update in dependent projects
        // TODO: Also do the Java elements, if they are in Jar files, since the library
        // projects do this (and the JDT refactoring does not include them)
        ProjectState projectState = Sdk.getProjectState(mProject);
        if (projectState != null) {
            Collection<ProjectState> parentProjects = projectState.getFullParentProjects();
            for (ProjectState parentProject : parentProjects) {
                IProject project = parentProject.getProject();
                IResource manifestResource = project.findMember(AdtConstants.WS_SEP
                        + SdkConstants.FN_ANDROID_MANIFEST_XML);
                if (manifestResource != null && manifestResource.exists()
                        && manifestResource instanceof IFile) {
                    addManifestFileChanges((IFile) manifestResource, result);
                }
                addLayoutFileChanges(project, result);
                addJavaChanges(project, result, pm);
            }
        }

        // Look for the field change on the R.java class; it's a derived file
        // and will generate file modified manually warnings. Disable it.
        RenameResourceParticipant.disableRClassChanges(result);

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

    private void addJavaChanges(IProject project, CompositeChange result, IProgressMonitor monitor) {
        if (!mIsCustomView) {
            return;
        }

        // Also rename styleables, if any
        try {
            // Find R class
            IJavaProject javaProject = BaseProjectHelper.getJavaProject(project);
            ManifestInfo info = ManifestInfo.get(project);
            info.getPackage();
            String rFqcn = info.getPackage() + '.' + R_CLASS;
            IType styleable = javaProject.findType(rFqcn + '.' + ResourceType.STYLEABLE.getName());
            if (styleable != null) {
                IField[] fields = styleable.getFields();
                CompositeChange fieldChanges = null;
                for (IField field : fields) {
                    String name = field.getElementName();
                    if (name.equals(mOldSimpleName) || name.startsWith(mOldSimpleName)
                            && name.length() > mOldSimpleName.length()
                            && name.charAt(mOldSimpleName.length()) == '_') {
                        // Rename styleable fields
                        String newName = name.equals(mOldSimpleName) ? mNewSimpleName :
                            mNewSimpleName + name.substring(mOldSimpleName.length());
                        RenameRefactoring refactoring =
                                RenameResourceParticipant.createFieldRefactoring(field,
                                        newName, true);

                        try {
                            sIgnore = true;
                            RefactoringStatus status = refactoring.checkAllConditions(monitor);
                            if (status != null && !status.hasError()) {
                                Change fieldChange = refactoring.createChange(monitor);
                                if (fieldChange != null) {
                                    if (fieldChanges == null) {
                                        fieldChanges = new CompositeChange(
                                                "Update custom view styleable fields");
                                        // Disable these changes. They sometimes end up
                                        // editing the wrong offsets. It looks like Eclipse
                                        // doesn't ensure that after applying each change it
                                        // also adjusts the other field offsets. I poked around
                                        // and couldn't find a way to do this properly, but
                                        // at least by listing the diffs here it shows what should
                                        // be done.
                                        fieldChanges.setEnabled(false);
                                    }
                                    // Disable change: see comment above.
                                    fieldChange.setEnabled(false);
                                    fieldChanges.add(fieldChange);
                                }
                            }
                        } catch (CoreException e) {
                            AdtPlugin.log(e, null);
                        } finally {
                            sIgnore = false;
                        }
                    }
                }
                if (fieldChanges != null) {
                    result.add(fieldChanges);
                }
            }
        } catch (CoreException e) {
            AdtPlugin.log(e, null);
        }
    }

    private void addManifestFileChanges(IFile manifestFile, CompositeChange result) {
        addXmlFileChanges(manifestFile, result, null);
    }

    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 &&
                        folderType != ResourceFolderType.VALUES) {
                    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, folderType);
                        }
                    }
                }
            }
        } catch (CoreException e) {
            RefactoringUtil.log(e);
        }
    }

    private boolean addXmlFileChanges(IFile file, CompositeChange changes,
            ResourceFolderType folderType) {
        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 (folderType == null) {
                            assert file.getName().equals(ANDROID_MANIFEST_XML);
                            addManifestReplacements(edits, root, document);
                        } else if (folderType == ResourceFolderType.VALUES) {
                            addValueReplacements(edits, root, document);
                        } else {
                            assert folderType == ResourceFolderType.LAYOUT;
                            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)) {
            // TODO: Handle inner classes ($ vs .) ?
            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));
                }
            } else if (classNode != null && classNode.getValue().equals(mOldDottedName)) {
                int start = RefactoringUtil.getAttributeValueRangeStart(classNode, document);
                if (start != -1) {
                    int end = start + mOldDottedName.length();
                    edits.add(new ReplaceEdit(start, end - start, mNewDottedName));
                }
            }
        }

        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 addValueReplacements(
            @NonNull List<TextEdit> edits,
            @NonNull Element root,
            @NonNull IStructuredDocument document) {
        // Look for styleable renames for custom views
        String declareStyleable = ResourceType.DECLARE_STYLEABLE.getName();
        List<Element> topLevel = DomUtilities.getChildren(root);
        for (Element element : topLevel) {
            String tag = element.getTagName();
            if (declareStyleable.equals(tag)) {
                Attr nameNode = element.getAttributeNode(ATTR_NAME);
                if (nameNode != null && mOldSimpleName.equals(nameNode.getValue())) {
                    int start = RefactoringUtil.getAttributeValueRangeStart(nameNode, document);
                    if (start != -1) {
                        int end = start + mOldSimpleName.length();
                        edits.add(new ReplaceEdit(start, end - start, mNewSimpleName));
                    }
                }
            }
        }
    }

    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.equals(mOldDottedName)) {
                int start = RefactoringUtil.getAttributeValueRangeStart(attr, document);
                if (start != -1) {
                    int end = start + mOldDottedName.length();
                    edits.add(new ReplaceEdit(start, end - start, mNewDottedName));
                }
            }
        }

        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);
            }
        }
    }
}