package com.jetbrains.env.django;

import com.google.common.collect.Lists;
import com.intellij.execution.configurations.ConfigurationFactory;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.jetbrains.django.run.DjangoServerRunConfiguration;
import com.jetbrains.django.run.DjangoServerRunConfigurationType;
import com.jetbrains.django.testRunner.DjangoTestsConfigurationType;
import com.jetbrains.django.testRunner.DjangoTestsRunConfiguration;
import com.jetbrains.env.python.debug.PyEnvTestCase;
import com.jetbrains.python.packaging.PyExternalProcessException;
import com.jetbrains.python.packaging.PyPackage;
import com.jetbrains.python.packaging.PyPackageManager;
import com.jetbrains.python.packaging.PyPackageManagerImpl;
import com.jetbrains.python.run.AbstractPythonRunConfiguration;
import junit.framework.Assert;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * User : catherine
 */
public class DjangoPathTest extends PyEnvTestCase {

  /**
   * This string is printed after printing sys.path in djangoPath/settings.py
   */
  public static final String THE_END_OF_SYS_PATH = "The end of sys.path";

  public void testRunserverPath() throws IOException {
    runPythonTest(new DjangoPathTestTask() {

      @Override
      protected void configure(AbstractPythonRunConfiguration config) throws IOException {
        final int[] ports = DjangoTemplateDebuggerTest.findFreePorts(2);
        ((DjangoServerRunConfiguration)config).setPort(ports[1]);
        ((DjangoServerRunConfiguration)config).setRunNoReload(true);
      }

      @Override
      public ConfigurationFactory getFactory() {
        return DjangoServerRunConfigurationType.getInstance().getConfigurationFactories()[0];
      }


      public void testing() throws Exception {
        waitForOutput(THE_END_OF_SYS_PATH);

        doTest(output(), getTestDataPath());
      }
    });
  }

  private static void doTest(String output, String testDataPath) {
    final String[] splittedOutput = output.split("\\n");
    final ArrayList<String> outputList = Lists.newArrayList();
    for (String s : splittedOutput) {
      if (s.equals(THE_END_OF_SYS_PATH)) {
        break;
      }
      outputList.add(norm(s));
    }

    testDataPath = norm(testDataPath);


    Assert.assertEquals(testDataPath, outputList.get(1));

    assertEquals(outputList.indexOf(testDataPath),
                 outputList.lastIndexOf(testDataPath));
  }

  private static String norm(String testDataPath) {
    return FileUtil.toSystemIndependentName(testDataPath);
  }

  public void testTestPath() throws IOException {
    runPythonTest(new DjangoPathTestTask() {

      @Override
      public ConfigurationFactory getFactory() {
        return DjangoTestsConfigurationType.getInstance().getConfigurationFactories()[0];
      }

      @Override
      protected void configure(AbstractPythonRunConfiguration config) {
        String target = "mysite.SimpleTest";
        try {
          final PyPackage django = ((PyPackageManagerImpl)PyPackageManager.getInstance(config.getSdk())).findPackage("django");
          if (django != null) {
            if (django.isVersionAtLeast(1,6))
              target = "mysite.tests.SimpleTest";
          }
        }
        catch (PyExternalProcessException ignored) {
        }

        ((DjangoTestsRunConfiguration)config).setTarget(target);
      }

      public void testing() throws Exception {
        waitForOutput(THE_END_OF_SYS_PATH);
        doTest(output(), getTestDataPath());
      }
    });
  }

  public void testManagePath() throws IOException {
    runPythonTest(new DjangoPathTestTask() {

      @Nullable
      @Override
      public ConfigurationFactory getFactory() {
        return null;
      }

      public void testing() throws Exception {
        waitForOutput(THE_END_OF_SYS_PATH);

        final String[] splittedOutput = output().split("\\n");
        final ArrayList<String> outputList = Lists.newArrayList();
        for (String s : splittedOutput) {
          if (s.equals(THE_END_OF_SYS_PATH)) {
            break;
          }
          outputList.add(s);
        }

        assertEquals(getTestDataPath(), outputList.get(1));
        assertEquals(outputList.indexOf(getTestDataPath()),
                     outputList.lastIndexOf(getTestDataPath()));
      }
    });
  }
}

@@ -185,58 +185,8 @@
 il;%0A
-import com.intellij.openapi.util.text.StringUtil;%0A
 impo
@@ -235,32 +235,32 @@
 nConfiguration;%0A
+
 import com.jetbr
@@ -541,199 +541,9 @@
 ing.
-PyExternalProcessException;%0Aimport com.jetbrains.python.packaging.PyPackage;%0Aimport com.jetbrains.python.packaging.PyPackageManager;%0Aimport com.jetbrains.python.packaging.PyPackageManagerImpl
+*
 ;%0Aim
@@ -703,24 +703,24 @@
 OException;%0A
+
 import java.
@@ -738,31 +738,8 @@
 ist;
-%0Aimport java.util.List;
 %0A%0A/*
@@ -2985,30 +2985,70 @@
 ngo.
-isVersionAtLeast(1,6))
+matches(PyRequirement.fromStringGuaranteed(%22django%3E=1.6a%22))) %7B
 %0A   
@@ -3086,32 +3086,46 @@
 ts.SimpleTest%22;%0A
+            %7D%0A
           %7D%0A    

Package method for checking version added