/*******************************************************************************
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
 *
 * 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 org.jetbrains.kotlin.ui.tests.editors;

import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import kotlin.Pair;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.eclipse.ui.utils.LineEndUtil;
import org.jetbrains.kotlin.testframework.editor.KotlinEditorAutoTestCase;
import org.jetbrains.kotlin.testframework.utils.KotlinTestUtils;
import org.jetbrains.kotlin.testframework.utils.SourceFileData;
import org.junit.Assert;

import com.google.common.collect.Lists;

public abstract class KotlinAnalyzerInIDETestCase extends KotlinEditorAutoTestCase {
    
    private static final String ANALYZER_TEST_DATA_PATH_SEGMENT = "ide_analyzer";
    
    private void performTest(IFile file, String expectedFileText) {
        try {
            configureProjectWithStdLibAndBuilder();
            file.touch(null);
            
            IMarker[] markers = file.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
            String actual = insertTagsForErrors(loadEclipseFile(file), markers);
            
            Assert.assertEquals(LineEndUtil.replaceAllSeparatorsWithSystemLineSeparators(expectedFileText), actual);
        } catch (CoreException e) {
            throw new RuntimeException(e);
        }
    }
    
    @Override
    protected void doSingleFileAutoTest(String testPath) {
        loadFilesToProjectAndDoTest(Collections.singletonList(new File(testPath)));
    }
    
    @Override
    protected void doMultiFileAutoTest(File testFolder) {
        loadFilesToProjectAndDoTest(Arrays.asList(testFolder.listFiles()));
    }
    
    private void loadFilesToProjectAndDoTest(@NotNull List<File> files) {
        List<Pair<IFile, String>> filesWithExpectedData = loadFilesToProject(files);
        for (Pair<IFile, String> fileAndExpectedData : filesWithExpectedData) {
            performTest(fileAndExpectedData.getFirst(), fileAndExpectedData.getSecond());
        }
    }
    
    private List<Pair<IFile, String>> loadFilesToProject(@NotNull List<File> files) {
        List<Pair<IFile, String>> filesWithExpectedData = Lists.newArrayList(); 
        for (File file : files) {
            String input = getText(file);
            input = LineEndUtil.replaceAllSeparatorsWithSystemLineSeparators(input);
            
            String resolvedInput = resolveTestTags(input);
            filesWithExpectedData.add(new Pair<IFile, String>(
                    createSourceFile(SourceFileData.getPackageFromContent(resolvedInput), file.getName(), 
                            resolveTestTags(resolvedInput)), 
                    input));
        }
        
        return filesWithExpectedData;
    }
    
    private String loadEclipseFile(IFile file) {
        return getText(file.getLocation().toFile());
    }
    
    private String insertTagsForErrors(String text, IMarker[] markers) throws CoreException {
        StringBuilder editorInput = new StringBuilder(text);
        int tagShift = 0;
        for (IMarker marker : markers) {
            if (marker.getAttribute(IMarker.SEVERITY, 0) == IMarker.SEVERITY_ERROR) {
                editorInput.insert((int) marker.getAttribute(IMarker.CHAR_START) + tagShift,
                        KotlinTestUtils.ERROR_TAG_OPEN);
                tagShift += KotlinTestUtils.ERROR_TAG_OPEN.length();
                
                editorInput.insert((int) marker.getAttribute(IMarker.CHAR_END) + tagShift,
                        KotlinTestUtils.ERROR_TAG_CLOSE);
                tagShift += KotlinTestUtils.ERROR_TAG_CLOSE.length();
            }
        }
        
        return editorInput.toString();
    }
    
    @Override
    protected String getTestDataRelativePath() {
        return ANALYZER_TEST_DATA_PATH_SEGMENT;
    }
    
    
    private void configureProjectWithStdLibAndBuilder() {
        try {
            KotlinTestUtils.addKotlinBuilder(testEditor.getEclipseProject());
            testEditor.getTestJavaProject().addKotlinRuntime();
            KotlinTestUtils.joinBuildThread();
        } catch (CoreException e) {
            throw new RuntimeException(e);
        }
    }
}

@@ -1051,16 +1051,77 @@
 source;%0A
+import org.eclipse.core.resources.IncrementalProjectBuilder;%0A
 import o
@@ -1205,66 +1205,8 @@
 ll;%0A
-import org.jetbrains.kotlin.eclipse.ui.utils.LineEndUtil;%0A
 impo
@@ -1276,16 +1276,81 @@
 stCase;%0A
+import org.jetbrains.kotlin.testframework.utils.EditorTestUtils;%0A
 import o
@@ -1473,33 +1473,8 @@
 ata;
-%0Aimport org.junit.Assert;
 %0A%0Aim
@@ -1858,32 +1858,186 @@
 );%0A            %0A
+            testEditor.getEclipseProject().build(IncrementalProjectBuilder.FULL_BUILD, null);%0A            KotlinTestUtils.joinBuildThread();%0A            %0A
             IMar
@@ -2229,85 +2229,57 @@
     
-Assert.assertEquals(LineEndUtil.replaceAllSeparatorsWithSystemLineSeparators(
+EditorTestUtils.assertByStringWithOffset(actual, 
 expe
@@ -2295,17 +2295,8 @@
 ext)
-, actual)
 ;%0A  
@@ -3317,106 +3317,8 @@
 e);%0A
-            input = LineEndUtil.replaceAllSeparatorsWithSystemLineSeparators(input);%0A            %0A
     
@@ -5005,55 +5005,8 @@
 ();%0A
-            KotlinTestUtils.joinBuildThread();%0A
     

Fix tests for analyzer: build project explicitly