package com.redhat.ceylon.eclipse.ui.test.swtbot;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEclipseEditor;
import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
import org.eclipse.swtbot.swt.finder.keyboard.Keystrokes;
import org.junit.After;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;

import com.redhat.ceylon.eclipse.ui.test.AbstractMultiProjectTest;
import com.redhat.ceylon.eclipse.ui.test.Utils;

@RunWith(SWTBotJunit4ClassRunner.class)
public class MainUITests extends AbstractMultiProjectTest {
    
    private static SWTWorkbenchBot  bot;
    
    @BeforeClass
    public static void beforeClass() throws InterruptedException {
        bot= Utils.createBot();
        
        importAndBuild();
    }
    
    @After
    public void after() {
        bot.closeAllEditors();
    }
    
    static protected abstract class NavigationStep {
        String match;
        int offset;
        String titleOfOpenedEditor;

        public NavigationStep(String match, int offset, String titleOfOpenedEditor) {
            this.match = match;
            this.offset = offset;
            this.titleOfOpenedEditor = titleOfOpenedEditor;
        }
        
        abstract void navigateToCurrentDeclaration(SWTBotEclipseEditor editor);
    }

    static protected class CtrlClick extends NavigationStep {
        public CtrlClick(String match, int offset, String titleOfOpenedEditor) {
            super(match, offset, titleOfOpenedEditor);
        }
        void navigateToCurrentDeclaration(SWTBotEclipseEditor editor) {
            Utils.ctrlClick(editor);
        }
    }
    
    static protected class GotoDeclaration extends NavigationStep {
        public GotoDeclaration(String match, int offset, String titleOfOpenedEditor) {
            super(match, offset, titleOfOpenedEditor);
        }
        void navigateToCurrentDeclaration(SWTBotEclipseEditor editor) {
            editor.pressShortcut(Keystrokes.F3);
        }
    }

    public void navigationTest(IFile initialFile, NavigationStep... navigationSteps) {
        Utils.openInEditor(initialFile);
        
        SWTBotEclipseEditor editor = Utils.showEditorByTitle(bot, initialFile.getName());
        for (NavigationStep step : navigationSteps) {
            editor.navigateTo(Utils.positionInTextEditor(editor, step.match, step.offset));
            bot.sleep(500);
            step.navigateToCurrentDeclaration(editor);
            bot.sleep(500);
            editor = Utils.showEditorByTitle(bot, step.titleOfOpenedEditor);
        }
    }

    @Test
    public void gotoDeclarationFromLanguageModuleSource() {
        navigationTest(mainProject.getFile("src/mainModule/run.ceylon"),
                new GotoDeclaration("doc ", 1, "annotations.ceylon"),
                new GotoDeclaration("\\bClassDeclaration\\b", 5, "ClassDeclaration.ceylon")
        );
    }

    
    @Test
    public void ctrlClickDeclarationFromLanguageModuleSource() {
        navigationTest(mainProject.getFile("src/mainModule/run.ceylon"),
                new CtrlClick("doc ", 1, "annotations.ceylon"),
                new CtrlClick("\\bClassDeclaration\\b", 5, "ClassDeclaration.ceylon")
        );
    }
    
    @Test
    public void gotoDeclarationOnJavaLangAdditions() throws CoreException {
        IFile initialFile = copyFileFromResources("navigateToSource", "mainModule/navigateToJavaLangAdditions.ceylon", mainProject, "src");
        try {
            navigationTest(initialFile,
                    new GotoDeclaration("ObjectArray", 3, "ObjectArray.class")
            );
            navigationTest(initialFile,
                    new GotoDeclaration("ByteArray", 3, "ByteArray.class")
            );
            navigationTest(initialFile,
                    new GotoDeclaration("IntArray", 3, "IntArray.class")
            );
            navigationTest(initialFile,
                    new GotoDeclaration("ShortArray", 3, "ShortArray.class")
            );
            navigationTest(initialFile,
                    new GotoDeclaration("FloatArray", 3, "FloatArray.class")
            );
            navigationTest(initialFile,
                    new GotoDeclaration("DoubleArray", 3, "DoubleArray.class")
            );
        } finally {
            initialFile.delete(true, null);
        }
    }

    
    @Test
    public void ctrlClickOnJavaLangAdditions() throws CoreException {
        IFile initialFile = copyFileFromResources("navigateToSource", "mainModule/navigateToJavaLangAdditions.ceylon", mainProject, "src");
        try {
            navigationTest(initialFile,
                    new CtrlClick("ObjectArray", 3, "ObjectArray.class")
            );
            navigationTest(initialFile,
                    new CtrlClick("ByteArray", 3, "ByteArray.class")
            );
            navigationTest(initialFile,
                    new CtrlClick("IntArray", 3, "IntArray.class")
            );
            navigationTest(initialFile,
                    new CtrlClick("ShortArray", 3, "ShortArray.class")
            );
            navigationTest(initialFile,
                    new CtrlClick("FloatArray", 3, "FloatArray.class")
            );
            navigationTest(initialFile,
                    new CtrlClick("DoubleArray", 3, "DoubleArray.class")
            );
        } finally {
            initialFile.delete(true, null);
        }
    }
}

@@ -44,16 +44,49 @@
 wtbot;%0A%0A
+import java.util.regex.Pattern;%0A%0A
 import o
@@ -118,16 +118,16 @@
 .IFile;%0A
-
 import o
@@ -1099,28 +1099,31 @@
         
-String match
+Pattern pattern
 ;%0A      
@@ -1279,22 +1279,213 @@
 this
-.match = match
+(Pattern.compile(match, Pattern.LITERAL), offset, titleOfOpenedEditor);%0A        %7D%0A        public NavigationStep(Pattern pattern, int offset, String titleOfOpenedEditor) %7B%0A            this.pattern = pattern
 ;%0A  
@@ -1882,32 +1882,183 @@
 tor);%0A        %7D%0A
+        public CtrlClick(Pattern pattern, int offset, String titleOfOpenedEditor) %7B%0A            super(pattern, offset, titleOfOpenedEditor);%0A        %7D%0A
         void nav
@@ -2383,32 +2383,189 @@
 tor);%0A        %7D%0A
+        public GotoDeclaration(Pattern pattern, int offset, String titleOfOpenedEditor) %7B%0A            super(pattern, offset, titleOfOpenedEditor);%0A        %7D%0A
         void nav
@@ -3037,21 +3037,23 @@
 r, step.
-match
+pattern
 , step.o
@@ -3515,16 +3515,32 @@
 aration(
+Pattern.compile(
 %22%5C%5CbClas
@@ -3547,32 +3547,33 @@
 sDeclaration%5C%5Cb%22
+)
 , 5, %22ClassDecla

Allow patterns and strings