package org.jetbrains.plugins.groovy.intentions.style.parameterToEntry;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.testFramework.UsefulTestCase;
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
import com.intellij.testFramework.fixtures.*;
import junit.framework.Assert;
import org.jetbrains.plugins.grails.fileType.GspFileType;
import org.jetbrains.plugins.groovy.GroovyFileType;
import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.util.TestUtils;

import java.io.*;

/**
 * @author ilyas
 */
public class ParameterToMapEntryTest extends UsefulTestCase {

  protected CodeInsightTestFixture myFixture;
  protected Project myProject;


  protected void setUp() throws Exception {
    super.setUp();
    final TestFixtureBuilder<IdeaProjectTestFixture> builder = JavaTestFixtureFactory.createFixtureBuilder();
    myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(builder.getFixture());
    final JavaModuleFixtureBuilder moduleBuilder = builder.addModule(JavaModuleFixtureBuilder.class);
    moduleBuilder.addJdk(TestUtils.getMockJdkHome());
    myFixture.setTestDataPath(TestUtils.getTestDataPath() + "/paramToMap" + "/" + getTestName(true));
    moduleBuilder.addContentRoot(myFixture.getTempDirPath()).addSourceRoot("");
    myFixture.setUp();

    myProject = myFixture.getProject();
    storeSettings();
    setSettings();
  }

  @Override
  protected CodeStyleSettings getCurrentCodeStyleSettings() {
    return CodeStyleSettingsManager.getSettings(myProject);
  }

  @Override
  protected void tearDown() throws Exception {
    CodeStyleSettingsManager.getInstance(myProject).dropTemporarySettings();
    checkForSettingsDamage();
    myFixture.tearDown();
    super.tearDown();
  }

  public void testParam1() throws Throwable {
    doTestImpl("A.groovy");
  }

  public void testFormatter() throws Throwable {
    doTestImpl("A.groovy");
  }

  public void testClosureAtEnd() throws Throwable {
    doTestImpl("A.groovy");
  }

  public void testClosure1() throws Throwable {
    doTestImpl("A.groovy");
  }

  public void testNewMap() throws Throwable {
    doTestImpl("A.groovy");
  }

  public void testTestError() throws Throwable {
    doTestImpl("A.groovy");
  }

  public void testSecondClosure() throws Throwable {
    doTestImpl("A.groovy");
  }

  private void doTestImpl(String filePath) throws Throwable {
    myFixture.configureByFile(filePath);
    int offset = myFixture.getEditor().getCaretModel().getOffset();
    final PsiFile file = myFixture.getFile();


    final ConvertParameterToMapEntryIntention intention = new ConvertParameterToMapEntryIntention();
    PsiElement element = file.findElementAt(offset);
    while (element != null && !(element instanceof GrReferenceExpression || element instanceof GrParameter)) {
      element = element.getParent();
    }
    Assert.assertNotNull(element);

    final PsiElementPredicate condition = intention.getElementPredicate();
    Assert.assertTrue(condition.satisfiedBy(element));

    // Launch it!
    intention.processIntention(element);
    final String result = file.getText();
    //System.out.println(result);
    String expected = getExpectedResult(filePath);
    Assert.assertEquals(result, expected);
  }

  private String getExpectedResult(final String filePath) {
    Assert.assertTrue(filePath.endsWith(".groovy"));
    String testFilePath = StringUtil.trimEnd(filePath, "groovy") + "test";

    final File file = new File(TestUtils.getTestDataPath() + "/paramToMap" + "/" + getTestName(true) + "/" + testFilePath);
    assertTrue(file.exists());
    String expected = "";

    try {
      BufferedReader reader = new BufferedReader(new FileReader(file));
      String line = reader.readLine();
      while (line != null) {
        expected += line;
        line = reader.readLine();
        if (line != null) expected += "\n";
      }
      reader.close();
    }
    catch (FileNotFoundException e) {
      e.printStackTrace();
    }
    catch (IOException e) {
      e.printStackTrace();
    }
    return expected;
  }

  private void setSettings() {
    CodeStyleSettings mySettings = getCurrentCodeStyleSettings().clone();
    mySettings.getIndentOptions(GroovyFileType.GROOVY_FILE_TYPE).INDENT_SIZE = 2;
    mySettings.getIndentOptions(GroovyFileType.GROOVY_FILE_TYPE).CONTINUATION_INDENT_SIZE = 4;
    mySettings.getIndentOptions(GroovyFileType.GROOVY_FILE_TYPE).TAB_SIZE = 2;
    mySettings.getIndentOptions(GspFileType.GSP_FILE_TYPE).INDENT_SIZE = 2;
    mySettings.getIndentOptions(GspFileType.GSP_FILE_TYPE).CONTINUATION_INDENT_SIZE = 4;
    mySettings.getIndentOptions(GspFileType.GSP_FILE_TYPE).TAB_SIZE = 2;
    CodeStyleSettingsManager.getInstance(myProject).setTemporarySettings(mySettings);
  }
}
@@ -509,98 +509,258 @@
 res.
-*;%0Aimport junit.framework.Assert;%0Aimport org.jetbrains.plugins.grails.fileType.GspFileType
+CodeInsightTestFixture;%0Aimport com.intellij.testFramework.fixtures.IdeaProjectTestFixture;%0Aimport com.intellij.testFramework.fixtures.JavaTestFixtureFactory;%0Aimport com.intellij.testFramework.fixtures.TestFixtureBuilder;%0Aimport junit.framework.Assert
 ;%0Aim
@@ -5067,246 +5067,8 @@
  2;%0A
-    mySettings.getIndentOptions(GspFileType.GSP_FILE_TYPE).INDENT_SIZE = 2;%0A    mySettings.getIndentOptions(GspFileType.GSP_FILE_TYPE).CONTINUATION_INDENT_SIZE = 4;%0A    mySettings.getIndentOptions(GspFileType.GSP_FILE_TYPE).TAB_SIZE = 2;%0A
     

remove unnecessary dependency