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

import static com.android.SdkConstants.FD_SOURCES;

import com.android.ide.common.resources.ResourceFile;
import com.android.ide.eclipse.adt.AdtUtils;
import com.android.ide.eclipse.adt.internal.editors.Hyperlinks.ResourceLink;
import com.android.ide.eclipse.adt.internal.editors.Hyperlinks.XmlResolver;
import com.android.ide.eclipse.adt.internal.editors.layout.refactoring.AdtProjectTest;

import org.eclipse.core.resources.IFile;
import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.swt.graphics.Point;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.internal.ErrorEditorPart;
import org.eclipse.ui.internal.browser.WebBrowserEditor;
import org.eclipse.wst.sse.ui.StructuredTextEditor;
import org.eclipse.wst.sse.ui.internal.StructuredTextViewer;
import org.eclipse.wst.xml.ui.internal.tabletree.XMLMultiPageEditorPart;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

@SuppressWarnings({
        "restriction", "javadoc"
})
public class HyperlinksTest extends AdtProjectTest {
    @Override
    protected boolean testCaseNeedsUniqueProject() {
        return true;
    }

    public void testFqnRegexp() throws Exception {
        assertTrue(Hyperlinks.isViewClassName("com.android.Foo"));
        assertTrue(Hyperlinks.isViewClassName("com.android.pk_g.Foo_Bar1"));
        assertTrue(Hyperlinks.isViewClassName("com.android.Foo$Inner"));

        // Should we allow non-standard packages and class names?
        // For now, we're allowing it -- see how this works out in practice.
        //assertFalse(XmlHyperlinkResolver.isViewClassName("Foo.bar"));
        assertTrue(Hyperlinks.isViewClassName("Foo.bar"));

        assertFalse(Hyperlinks.isViewClassName("LinearLayout"));
        assertFalse(Hyperlinks.isViewClassName("."));
        assertFalse(Hyperlinks.isViewClassName(".F"));
        assertFalse(Hyperlinks.isViewClassName("f."));
        assertFalse(Hyperlinks.isViewClassName("Foo"));
        assertFalse(Hyperlinks.isViewClassName("com.android.1Foo"));
        assertFalse(Hyperlinks.isViewClassName("1com.Foo"));
    }

    public void testNavigate1() throws Exception {
        // Check navigating to a local resource
        checkXmlNavigation("navigation1.xml", "res/layout/navigation1.xml",
                "android:text=\"@string/app^_name\"");
    }

    public void testNavigate2() throws Exception {
        // Check navigating to a framework resource
        checkXmlNavigation("navigation1.xml", "res/layout/navigation1.xml",
                "marginLeft=\"@android:dimen/app_ico^n_size\"");
    }

    public void testNavigate3() throws Exception {
        // Check navigating to a style
        checkXmlNavigation("navigation1.xml", "res/layout/navigation1.xml",
                "style=\"@android:style/Widget.B^utton\"");
    }

    public void testNavigate4() throws Exception {
        // Check navigating to resource with many resolutions
        checkXmlNavigation("navigation1.xml", "res/layout/navigation1.xml",
                "android:text=\"@android:st^ring/ok\"");
    }

    public void testNavigate5() throws Exception {
        // Check navigating to styles
        checkXmlNavigation("navigationstyles.xml", "res/values/navigationstyles.xml",
                "parent=\"android:Theme.Li^ght\">");
    }

    public void testNavigate6() throws Exception {
        // Check navigating to a portion of a style (this should pick android:Theme, not
        // android:Theme.Light
        checkXmlNavigation("navigationstyles.xml", "res/values/navigationstyles.xml",
                "parent=\"android:The^me.Light\">");
    }

    public void testNavigate7() throws Exception {
        // Check navigating to a resource inside text content
        checkXmlNavigation("navigationstyles.xml", "res/values/navigationstyles.xml",
                "popupBackground\">@android:drawable/spinner_dr^opdown_background</item>");
    }

    public void testNavigate8() throws Exception {
        // Check navigating to a resource inside text content where there is space around
        // the URL
        checkXmlNavigation("navigationstyles.xml", "res/values/navigationstyles.xml",
                "colorBackground\"> @color/cust^om_theme_color </item>");
    }

    public void testNavigate9a() throws Exception {
        // Check navigating to a an activity
        checkXmlNavigation("manifest.xml", "AndroidManifest.xml",
                "<activity android:name=\".Test^Activity\"");
    }

    /* Not yet implemented
    public void testNavigate9b() throws Exception {
        // Check navigating to a an activity - clicking on the activity element should
        // work too
        checkXmlNavigation("manifest.xml", "AndroidManifest.xml",
                "<acti^vity android:name=\".TestActivity\"");
    }
    */

    public void testNavigate10() throws Exception {
        // Check navigating to a permission
        checkXmlNavigation("manifest.xml", "AndroidManifest.xml",
                "<uses-permission android:name=\"android.permission.AC^CESS_NETWORK_STATE\" />");
    }

    public void testNavigate11a() throws Exception {
        // Check navigating to an intent
        checkXmlNavigation("manifest.xml", "AndroidManifest.xml",
                "<action android:name=\"android.intent.ac^tion.MAIN\" />");
    }

    public void testNavigate11g() throws Exception {
        // Check navigating to an intent
        checkXmlNavigation("manifest.xml", "AndroidManifest.xml",
                "<category android:name=\"android.intent.category.LA^UNCHER\" />");
    }

    public void testNavigate12() throws Exception {
        // Check navigating to a custom view class
        checkXmlNavigation("navigation1.xml", "res/layout/navigation1.xml",
                "<my.Cust^omView></my.CustomView>");
    }

    public void testNavigate13() throws Exception {
        // Check jumping to classes pointed to by fragments

        getTestDataFile(getProject(), "TestFragment.java.txt",
                FD_SOURCES + "/" + TEST_PROJECT_PACKAGE.replace('.', '/') + "/TestFragment.java");
        checkXmlNavigation("fragmentlayout.xml", "res/layout/fragmentlayout.xml",
                "android:name=\"com.android.ecl^ipse.tests.TestFragment\"");
    }

    public void testNavigate14() throws Exception {
        // Check jumping to classes pointed to by fragments

        getTestDataFile(getProject(), "TestFragment.java.txt",
                FD_SOURCES + "/" + TEST_PROJECT_PACKAGE.replace('.', '/') + "/TestFragment.java");
        checkXmlNavigation("fragmentlayout.xml", "res/layout/fragmentlayout.xml",
                "class=\"com.and^roid.eclipse.tests.TestFragment\"");
    }

    public void testNavigate15() throws Exception {
        // Check navigating to a theme resource
        checkXmlNavigation("navigation1.xml", "res/layout/navigation1.xml",
                "?android:attr/alert^DialogStyle");
    }

    public void testNavigate16() throws Exception {
        // Check navigating to a theme resource
        checkXmlNavigation("navigation1.xml", "res/layout/navigation1.xml",
                "?android:alert^DialogStyle");
    }

    // Left to test:
    // onClick handling
    // class attributes
    // Test that the correct file is actually opened!

    private void checkXmlNavigation(String basename, String targetPath,
            String caretLocation) throws Exception {
        IFile file = getTestDataFile(getProject(), basename, targetPath, true);

        // Determine the offset
        int offset = getCaretOffset(file, caretLocation);

        // Open file
        IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
        assertNotNull(page);
        IEditorPart editor = IDE.openEditor(page, file);
        assertTrue(editor.getClass().getName(), editor instanceof AndroidXmlEditor);
        AndroidXmlEditor layoutEditor = (AndroidXmlEditor) editor;
        ISourceViewer viewer = layoutEditor.getStructuredSourceViewer();

        XmlResolver resolver = new Hyperlinks.XmlResolver();
        IHyperlink[] links = resolver.detectHyperlinks(viewer, new Region(offset, 0), true);
        assertNotNull(links);

        StringBuilder sb = new StringBuilder(1000);
        sb.append("Go To Declaration in " + basename + " for " + caretLocation + ":\n");
        for (IHyperlink link : links) {
            sb.append(link.getHyperlinkText());
            sb.append(" : ");
            sb.append(" [");
            IRegion region = link.getHyperlinkRegion();
            sb.append(viewer.getDocument().get(region.getOffset(), region.getLength()));
            sb.append("]");
            if (link instanceof Hyperlinks.ResourceLink) {
                Hyperlinks.ResourceLink resourceLink = (ResourceLink) link;
                sb.append("\n    ");
                ResourceFile resourceFile = resourceLink.getFile();
                String desc = resourceFile.toString();
                desc = desc.replace('\\', '/');
                // For files in the SDK folder, strip out file prefix
                int dataRes = desc.indexOf("data/res");
                if (dataRes != -1) {
                    desc = desc.substring(dataRes);
                }
                desc = removeSessionData(desc);
                sb.append(desc);
            }
            sb.append('\n');
        }

        // Open the first link
        IHyperlink link = links[0];
        link.open();
        IEditorPart newEditor = AdtUtils.getActiveEditor();
        // Ensure that this isn't an invalid file (e.g. opening the SDK platform files
        // with incorrect content binding could cause this)
        assertTrue(!(newEditor instanceof ErrorEditorPart));

        IDocument document = null;
        Point selection = null;

        if (newEditor instanceof AndroidXmlEditor) {
            AndroidXmlEditor xmlEditor = (AndroidXmlEditor) newEditor;
            document = xmlEditor.getStructuredSourceViewer().getDocument();
            selection = xmlEditor.getStructuredSourceViewer().getSelectedRange();
        } else if (newEditor instanceof XMLMultiPageEditorPart) {
            XMLMultiPageEditorPart xmlEditor = (XMLMultiPageEditorPart) newEditor;
            Field field = xmlEditor.getClass().getDeclaredField("fTextEditor");
            field.setAccessible(true);
            StructuredTextEditor ste = (StructuredTextEditor) field.get(newEditor);
            if (ste == null) {
                Method method = xmlEditor.getClass().getMethod("getTextEditor", new Class[0]);
                ste = (StructuredTextEditor) method.invoke(newEditor, new Object[0]);
            }
            StructuredTextViewer textViewer = ste.getTextViewer();
            document = textViewer.getDocument();
            selection = textViewer.getSelectedRange();
        } else if (newEditor instanceof WebBrowserEditor) {
            WebBrowserEditor browser = (WebBrowserEditor) newEditor;
            Field field = browser.getClass().getDeclaredField("initialURL");
            field.setAccessible(true);
            String initialUrl = (String) field.get(newEditor);
            int index = initialUrl.indexOf("reference");
            if (index != -1) {
                initialUrl = initialUrl.substring(index);
            }
            initialUrl = initialUrl.replace('\\', '/');
            sb.append("\n\nAfter open, a browser is shown with this URL:\n");
            sb.append("  ");
            sb.append(initialUrl);
            sb.append("\n");
        } else if (newEditor instanceof JavaEditor) {
            JavaEditor javaEditor = (JavaEditor) newEditor;
            document = javaEditor.getDocumentProvider().getDocument(javaEditor.getEditorInput());
            IRegion range = javaEditor.getHighlightRange();
            selection = new Point(range.getOffset(), range.getLength());
        } else {
            fail("Unhandled editor type: " + newEditor.getClass().getName());
            return;
        }

        if (document != null && selection != null) {
            int lineStart = document.getLineInformationOfOffset(selection.x).getOffset();
            IRegion lineEndInfo = document.getLineInformationOfOffset(selection.x + selection.y);
            int lineEnd = lineEndInfo.getOffset() + lineEndInfo.getLength();
            String text = document.get(lineStart, lineEnd - lineStart);
            int selectionStart = selection.x - lineStart;
            int selectionEnd = selectionStart + selection.y;
            if (selectionEnd > selectionStart) {
                // Selection range
                text = text.substring(0, selectionStart) + "[^" +
                   text.substring(selectionStart, selectionEnd) + "]" +
                   text.substring(selectionEnd);
            } else {
                text = text.substring(0, selectionStart) + "^" +
                    text.substring(selectionStart);
            }
            text = removeSessionData(text);

            sb.append("\n\nAfter open, the selected text is:\n");
            sb.append(text);
            sb.append("\n");
        }

        assertEqualsGolden(basename, sb.toString(), "txt");
    }
}
