/*
 * 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.refactorings.core;

import static com.android.SdkConstants.ANDROID_MANIFEST_XML;
import static com.android.SdkConstants.ANDROID_PREFIX;
import static com.android.SdkConstants.ANDROID_THEME_PREFIX;
import static com.android.SdkConstants.ATTR_NAME;
import static com.android.SdkConstants.ATTR_TYPE;
import static com.android.SdkConstants.TAG_ITEM;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.common.resources.ResourceUrl;
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.BaseProjectHelper;
import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.resources.ResourceType;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.internal.corext.refactoring.rename.RenameTypeProcessor;
import org.eclipse.jdt.internal.ui.refactoring.reorg.RenameTypeWizard;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.ltk.core.refactoring.participants.RenameRefactoring;
import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.texteditor.ITextEditorExtension;
import org.eclipse.ui.texteditor.ITextEditorExtension2;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import java.util.List;

/**
 * Text action for XML files to invoke renaming
 * <p>
 * TODO: Handle other types of renaming: invoking class renaming when editing
 * class names in layout files and manifest files, renaming attribute names when
 * editing a styleable attribute, etc.
 */
@SuppressWarnings("restriction") // Java rename refactoring
public final class RenameResourceXmlTextAction extends Action {
    private final ITextEditor mEditor;

    /**
     * Creates a new {@linkplain RenameResourceXmlTextAction}
     *
     * @param editor the associated editor
     */
    public RenameResourceXmlTextAction(@NonNull ITextEditor editor) {
        super("Rename");
        mEditor = editor;
    }

    @Override
    public void run() {
        if (!validateEditorInputState()) {
            return;
        }
        IFile file = getFile();
        if (file == null) {
            return;
        }
        IProject project = file.getProject();
        if (project == null) {
            return;
        }
        IDocument document = getDocument();
        if (document == null) {
            return;
        }
        ITextSelection selection = getSelection();
        if (selection == null) {
            return;
        }

        ResourceUrl resource = findResource(document, selection.getOffset());

        if (resource == null) {
            resource = findItemDefinition(document, selection.getOffset());
        }

        if (resource != null) {
            ResourceType type = resource.type;
            String name = resource.name;
            Shell shell = mEditor.getSite().getShell();
            boolean canClear = false;

            RenameResourceWizard.renameResource(shell, project, type, name, null, canClear);
            return;
        }

        String className = findClassName(document, file, selection.getOffset());
        if (className != null) {
            assert className.equals(className.trim());
            IType type = findType(className, project);
            if (type != null) {
                RenameTypeProcessor processor = new RenameTypeProcessor(type);
                //processor.setNewElementName(className);
                processor.setUpdateQualifiedNames(true);
                processor.setUpdateSimilarDeclarations(false);
                //processor.setMatchStrategy(?);
                //processor.setFilePatterns(patterns);
                processor.setUpdateReferences(true);

                RenameRefactoring refactoring = new RenameRefactoring(processor);
                RenameTypeWizard wizard = new RenameTypeWizard(refactoring);
                RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(wizard);
                try {
                    IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
                    op.run(window.getShell(), wizard.getDefaultPageTitle());
                } catch (InterruptedException e) {
                }
            }

            return;
        }

        // Fallback: tell user the cursor isn't in the right place
        MessageDialog.openInformation(mEditor.getSite().getShell(),
                "Rename",
                "Operation unavailable on the current selection.\n"
                        + "Select an Android resource name or class.");
    }

    private boolean validateEditorInputState() {
        if (mEditor instanceof ITextEditorExtension2)
            return ((ITextEditorExtension2) mEditor).validateEditorInputState();
        else if (mEditor instanceof ITextEditorExtension)
            return !((ITextEditorExtension) mEditor).isEditorInputReadOnly();
        else if (mEditor != null)
            return mEditor.isEditable();
        else
            return false;
    }

    /**
     * Searches for a resource URL around the caret, such as {@code @string/foo}
     *
     * @param document the document to search in
     * @param offset the offset to search at
     * @return a resource pair, or null if not found
     */
    @Nullable
    public static ResourceUrl findResource(@NonNull IDocument document, int offset) {
        try {
            int max = document.getLength();
            if (offset >= max) {
                offset = max - 1;
            } else if (offset < 0) {
                offset = 0;
            } else if (offset > 0) {
                // If the caret is right after a resource name (meaning getChar(offset) points
                // to the following character), back up
                char c = document.getChar(offset);
                if (!isValidResourceNameChar(c)) {
                    offset--;
                }
            }

            int start = offset;
            boolean valid = true;
            for (; start >= 0; start--) {
                char c = document.getChar(start);
                if (c == '@' || c == '?') {
                    break;
                } else if (!isValidResourceNameChar(c)) {
                    valid = false;
                    break;
                }
            }
            if (valid) {
                // Search forwards for the end
                int end = start + 1;
                for (; end < max; end++) {
                    char c = document.getChar(end);
                    if (!isValidResourceNameChar(c)) {
                        break;
                    }
                }
                if (end > start + 1) {
                    String url = document.get(start, end - start);

                    // Don't allow renaming framework resources -- @android:string/ok etc
                    if (url.startsWith(ANDROID_PREFIX) || url.startsWith(ANDROID_THEME_PREFIX)) {
                        return null;
                    }

                    return ResourceUrl.parse(url);
                }
            }
        } catch (BadLocationException e) {
            AdtPlugin.log(e, null);
        }

        return null;
    }

    private static boolean isValidResourceNameChar(char c) {
        return c == '@' || c == '?' || c == '/' || c == '+' || Character.isJavaIdentifierPart(c);
    }

    /**
     * Searches for an item definition around the caret, such as
     * {@code   <string name="foo">My String</string>}
     */
    private ResourceUrl findItemDefinition(IDocument document, int offset) {
        Node node = DomUtilities.getNode(document, offset);
        if (node == null) {
            return null;
        }
        if (node.getNodeType() == Node.TEXT_NODE) {
            node = node.getParentNode();
        }
        if (node == null || node.getNodeType() != Node.ELEMENT_NODE) {
            return null;
        }

        Element element = (Element) node;
        String name = element.getAttribute(ATTR_NAME);
        if (name == null || name.isEmpty()) {
            return null;
        }
        String typeString = element.getTagName();
        if (TAG_ITEM.equals(typeString)) {
            typeString = element.getAttribute(ATTR_TYPE);
            if (typeString == null || typeString.isEmpty()) {
                return null;
            }
        }
        ResourceType type = ResourceType.getEnum(typeString);
        if (type != null) {
            return ResourceUrl.create(type, name, false, false);
        }

        return null;
    }

    /**
     * Searches for a fully qualified class name around the caret, such as {@code foo.bar.MyClass}
     *
     * @param document the document to search in
     * @param file the file, if known
     * @param offset the offset to search at
     * @return a resource pair, or null if not found
     */
    @Nullable
    public static String findClassName(
            @NonNull IDocument document,
            @Nullable IFile file,
            int offset) {
        try {
            int max = document.getLength();
            if (offset >= max) {
                offset = max - 1;
            } else if (offset < 0) {
                offset = 0;
            } else if (offset > 0) {
                // If the caret is right after a resource name (meaning getChar(offset) points
                // to the following character), back up
                char c = document.getChar(offset);
                if (Character.isJavaIdentifierPart(c)) {
                    offset--;
                }
            }

            int start = offset;
            for (; start >= 0; start--) {
                char c = document.getChar(start);
                if (c == '"' || c == '<' || c == '/') {
                    start++;
                    break;
                } else if (c != '.' && !Character.isJavaIdentifierPart(c)) {
                    return null;
                }
            }
            // Search forwards for the end
            int end = start + 1;
            for (; end < max; end++) {
                char c = document.getChar(end);
                if (c != '.' && !Character.isJavaIdentifierPart(c)) {
                    if (c != '"' && c != '>' && !Character.isWhitespace(c)) {
                        return null;
                    }
                    break;
                }
            }
            if (end > start + 1) {
                String fqcn = document.get(start, end - start);
                int dot = fqcn.indexOf('.');
                if (dot == -1) { // Only support fully qualified names
                    return null;
                }
                if (dot == 0) { // Special case for manifests: prepend package
                    if (file != null && file.getName().equals(ANDROID_MANIFEST_XML)) {
                        ManifestInfo info = ManifestInfo.get(file.getProject());
                        return info.getPackage() + fqcn;
                    }
                    return null;
                }

                return fqcn;
            }
        } catch (BadLocationException e) {
            AdtPlugin.log(e, null);
        }

        return null;
    }

    @Nullable
    private IType findType(@NonNull String className, @NonNull IProject project) {
        IType type = null;
        try {
            IJavaProject javaProject = BaseProjectHelper.getJavaProject(project);
            type = javaProject.findType(className);
            if (type == null || !type.exists()) {
                return null;
            }
            if (!type.isBinary()) {
                return type;
            }
            // See if this class is coming through a library project jar file and
            // if so locate the real class
            ProjectState projectState = Sdk.getProjectState(project);
            if (projectState != null) {
                List<IProject> libraries = projectState.getFullLibraryProjects();
                for (IProject library : libraries) {
                    javaProject = BaseProjectHelper.getJavaProject(library);
                    type = javaProject.findType(className);
                    if (type != null && type.exists() && !type.isBinary()) {
                        return type;
                    }
                }
            }
        } catch (CoreException e) {
            AdtPlugin.log(e, null);
        }

        return null;
    }

    private ITextSelection getSelection() {
        ISelectionProvider selectionProvider = mEditor.getSelectionProvider();
        if (selectionProvider == null) {
            return null;
        }
        ISelection selection = selectionProvider.getSelection();
        if (!(selection instanceof ITextSelection)) {
            return null;
        }
        return (ITextSelection) selection;
    }

    private IDocument getDocument() {
        IDocumentProvider documentProvider = mEditor.getDocumentProvider();
        if (documentProvider == null) {
            return null;
        }
        IDocument document = documentProvider.getDocument(mEditor.getEditorInput());
        if (document == null) {
            return null;
        }
        return document;
    }

    @Nullable
    private IFile getFile() {
        IEditorInput input = mEditor.getEditorInput();
        if (input instanceof IFileEditorInput) {
            IFileEditorInput fileInput = (IFileEditorInput) input;
            return fileInput.getFile();
        }

        return null;
    }
}
