package com.jetbrains.python.fixtures;

import com.intellij.openapi.module.EmptyModuleType;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiReference;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.TestDataPath;
import com.intellij.testFramework.UsefulTestCase;
import com.intellij.testFramework.fixtures.CodeInsightTestFixture;
import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
import com.intellij.testFramework.fixtures.TestFixtureBuilder;
import com.intellij.testFramework.fixtures.impl.LightTempDirTestFixtureImpl;
import com.jetbrains.python.PythonMockSdk;
import com.jetbrains.python.PythonTestUtil;
import com.jetbrains.python.psi.LanguageLevel;
import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher;
import org.jetbrains.annotations.Nullable;

/**
 * @author yole
 */
@TestDataPath("$CONTENT_ROOT/../testData/")
public abstract class PyLightFixtureTestCase extends UsefulTestCase {
  private static final PyLightProjectDescriptor ourPyDescriptor = new PyLightProjectDescriptor("2.5");
  protected static final PyLightProjectDescriptor ourPy3Descriptor = new PyLightProjectDescriptor("3.1");

  protected CodeInsightTestFixture myFixture;
  private static boolean ourPlatformPrefixInitialized;

  @Override
  protected void setUp() throws Exception {
    super.setUp();
    initPlatformPrefix();
    IdeaTestFixtureFactory factory = IdeaTestFixtureFactory.getFixtureFactory();
    TestFixtureBuilder<IdeaProjectTestFixture> fixtureBuilder = factory.createLightFixtureBuilder(getProjectDescriptor());
    final IdeaProjectTestFixture fixture = fixtureBuilder.getFixture();
    myFixture = IdeaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(fixture,
                                                                                    new LightTempDirTestFixtureImpl(true));
    myFixture.setUp();

    myFixture.setTestDataPath(getTestDataPath());
  }

  protected String getTestDataPath() {
    return PythonTestUtil.getTestDataPath();
  }

  @Override
  protected void tearDown() throws Exception {
    myFixture.tearDown();
    myFixture = null;
    super.tearDown();
  }

  @Nullable
  protected LightProjectDescriptor getProjectDescriptor() {
    return ourPyDescriptor;
  }

  protected PsiReference findReferenceBySignature(final String signature) {
    int pos = findPosBySignature(signature);
    return findReferenceAt(pos);
  }

  protected PsiReference findReferenceAt(int pos) {
    return myFixture.getFile().findReferenceAt(pos);
  }

  protected int findPosBySignature(String signature) {
    return PsiDocumentManager.getInstance(myFixture.getProject()).getDocument(myFixture.getFile()).getText().indexOf(signature);
  }

  protected void setLanguageLevel(LanguageLevel languageLevel) {
    PythonLanguageLevelPusher.setForcedLanguageLevel(myFixture.getProject(), languageLevel);
  }

  protected static class PyLightProjectDescriptor implements LightProjectDescriptor {
    private final String myPythonVersion;

    public PyLightProjectDescriptor(String pythonVersion) {
      myPythonVersion = pythonVersion;
    }

    @Override
    public ModuleType getModuleType() {
      return EmptyModuleType.getInstance();
    }

    @Override
    public Sdk getSdk() {
      return PythonMockSdk.findOrCreate(myPythonVersion);
    }

    @Override
    public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) {
    }
  }

  public static void initPlatformPrefix() {
    if (!ourPlatformPrefixInitialized) {
      ourPlatformPrefixInitialized = true;
      boolean isIDEA = true;
      try {
        PyLightFixtureTestCase.class.getClassLoader().loadClass("com.intellij.openapi.project.impl.IdeaProjectManagerImpl");
      }
      catch (ClassNotFoundException e) {
        isIDEA = false;
      }
      if (!isIDEA) {
        System.setProperty("idea.platform.prefix", "Python");
      }
    }
  }
}

@@ -33,16 +33,69 @@
 tures;%0A%0A
+import com.intellij.openapi.application.PathManager;%0A
 import c
@@ -373,24 +373,220 @@
 eRootModel;%0A
+import com.intellij.openapi.roots.OrderRootType;%0Aimport com.intellij.openapi.roots.libraries.Library;%0Aimport com.intellij.openapi.vfs.LocalFileSystem;%0Aimport com.intellij.openapi.vfs.VirtualFile;%0A
 import com.i
@@ -4029,24 +4029,479 @@
 try) %7B%0A    %7D
+%0A%0A    protected void createLibrary(ModifiableRootModel model, final String name, final String path) %7B%0A      final Library.ModifiableModel modifiableModel = model.getModuleLibraryTable().createLibrary(name).getModifiableModel();%0A      final VirtualFile home =%0A        LocalFileSystem.getInstance().refreshAndFindFileByPath(PathManager.getHomePath() + path);%0A%0A      modifiableModel.addRoot(home, OrderRootType.CLASSES);%0A      modifiableModel.commit();%0A    %7D
 %0A  %7D%0A%0A  publ

configure App Engine library in App Engine tests