package tests.wurstscript.tests;

import com.google.common.collect.ImmutableMap;
import de.peeeq.wurstio.WurstCompilerJassImpl;
import de.peeeq.wurstio.languageserver.BufferManager;
import de.peeeq.wurstio.languageserver.ModelManager;
import de.peeeq.wurstio.languageserver.ModelManagerImpl;
import de.peeeq.wurstio.languageserver.WFile;
import de.peeeq.wurstio.languageserver.requests.GetDefinition;
import de.peeeq.wurstscript.RunArgs;
import de.peeeq.wurstscript.ast.WurstModel;
import de.peeeq.wurstscript.gui.WurstGui;
import de.peeeq.wurstscript.gui.WurstGuiLogger;
import org.eclipse.lsp4j.*;
import org.testng.annotations.Test;

import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;

/**
 * tests the get definition functionality.
 * <p>
 * the position of the cursor is denoted by a bar "|" in the test cases
 */
public class GetDefinitionTests extends WurstLanguageServerTest {


    @Test
    public void simpleExample1() {
        CompletionTestData testData = input(
                "package test",
                "	function int.foo()",
                "	function int.bar()",
                "	init",
                "		int x = 5",
                "		int y = x| + 5",
                "endpackage"
        );

        testGetDef(testData, "4:6-4:7");
    }

    @Test
    public void superConstructorCall() {
        CompletionTestData testData = input(
                "package test",
                "class C",
                "    construct(string s)",
                "    construct(int x)",
                "class D extends C",
                "    construct()",
                "        sup|er(8)",
                "endpackage"
        );

        testGetDef(testData, "3:4-3:13");
    }

    @Test
    public void nonexistantModule() {
        CompletionTestData testData = input(
                "package test",
                "class A",
                "	use B|lub"
        );

        testGetDef(testData, Collections.emptyList());
    }


    private void testGetDef(CompletionTestData testData, String... expectedPositions) {
        testGetDef(testData, Arrays.asList(expectedPositions));
    }

    private void testGetDef(CompletionTestData testData, List<String> expectedPositions) {

        List<? extends Location> result = calculateDefinition(testData);

        List<String> definitions = result.stream()
                .map((Location l) -> l.getRange().getStart().getLine() + ":" + l.getRange().getStart().getCharacter() + "-" + l.getRange().getEnd().getLine() + ":" + l.getRange().getEnd().getCharacter())
                .sorted()
                .collect(Collectors.toList());


        assertEquals(definitions, expectedPositions);
    }

    private List<? extends Location> calculateDefinition(CompletionTestData testData) {
        BufferManager bufferManager = new BufferManager();
        File projectPath = new File("./test-output").getAbsoluteFile();
        ModelManager modelManager = new ModelManagerImpl(projectPath, bufferManager);
        String uri = projectPath.toURI().toString() + "/wurst/test.wurst";
        bufferManager.updateFile(WFile.create(uri), testData.buffer);
        TextDocumentIdentifier textDocument = new TextDocumentIdentifier(uri);
        Position pos = new Position(testData.line, testData.column);
        CompletionParams position = new CompletionParams(textDocument, pos);
        GetDefinition getDefinition = new GetDefinition(position, bufferManager);

        //new GetCompletions(1, "test", testData.buffer, testData.line, testData.column);

        return getDefinition.execute(modelManager);
    }


}

@@ -31,102 +31,8 @@
 s;%0A%0A
-import com.google.common.collect.ImmutableMap;%0Aimport de.peeeq.wurstio.WurstCompilerJassImpl;%0A
 impo
@@ -311,170 +311,27 @@
 ort 
-de.peeeq.wurstscript.RunArgs;%0Aimport de.peeeq.wurstscript.ast.WurstModel;%0Aimport de.peeeq.wurstscript.gui.WurstGui;%0Aimport de.peeeq.wurstscript.gui.WurstGuiLogger
+org.eclipse.lsp4j.*
 ;%0Aim
@@ -345,33 +345,55 @@
 g.eclipse.lsp4j.
-*
+jsonrpc.messages.Either
 ;%0Aimport org.tes
@@ -453,17 +453,22 @@
 va.util.
-*
+Arrays
 ;%0Aimport
@@ -482,74 +482,81 @@
 til.
-stream.
 Collect
-or
+ion
 s;%0A
-%0A
 import 
-static org.testng.Assert.assertEqual
+java.util.List;%0Aimport java.util.stream.Collector
 s;%0A
+%0A
 impo
@@ -593,13 +593,14 @@
 sert
-F
+Equ
 als
-e
 ;%0A%0A/
@@ -2125,24 +2125,31 @@
  %7B%0A%0A        
+Either%3C
 List%3C? exten
@@ -2160,16 +2160,47 @@
 ocation%3E
+, List%3C? extends LocationLink%3E%3E
  result 
@@ -2232,25 +2232,24 @@
 tData);%0A
-%0A
         
 List%3CStr
@@ -2240,16 +2240,42 @@
         
+if (result.isLeft()) %7B%0A%09%09%09
 List%3CStr
@@ -2304,33 +2304,31 @@
 ult.
-stream()%0A                
+getLeft().stream()%0A%09%09%09%09
 .map
@@ -2515,50 +2515,413 @@
 ())%0A
-                .sorted()%0A                
+%09%09%09%09.sorted()%0A%09%09%09%09.collect(Collectors.toList());%0A%0A%09%09%09assertEquals(definitions, expectedPositions);%0A%09%09%7D else %7B%0A%09%09%09List%3CString%3E definitions = result.getRight().stream()%0A%09%09%09%09.map((LocationLink l) -%3E l.getTargetRange().getStart().getLine() + %22:%22 + l.getTargetRange().getStart().getCharacter() + %22-%22 + l.getTargetRange().getEnd().getLine() + %22:%22 + l.getTargetRange().getEnd().getCharacter())%0A%09%09%09%09.sorted()%0A%09%09%09%09
 .col
@@ -2948,25 +2948,19 @@
 st());%0A%0A
-%0A        
+%09%09%09
 assertEq
@@ -2993,24 +2993,28 @@
 Positions);%0A
+%09%09%7D%0A
     %7D%0A%0A    p
@@ -3020,16 +3020,23 @@
 private 
+Either%3C
 List%3C? e
@@ -3051,16 +3051,47 @@
 ocation%3E
+, List%3C? extends LocationLink%3E%3E
  calcula

Fix GetDefinitionTests