/*
 * Copyright 2000-2016 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.idea.maven.server;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.testFramework.EdtTestUtil;
import com.intellij.testFramework.PlatformTestUtil;
import org.jetbrains.idea.maven.MavenTestCase;
import org.jetbrains.idea.maven.project.MavenWorkspaceSettingsComponent;

import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class MavenServerManagerTest extends MavenTestCase {
  public void testInitializingDoesntTakeReadAction() throws Exception {
    //make sure all components are initialized to prevent deadlocks
    MavenServerManager.getInstance().getConnector(myProject, myProjectRoot.getPath());

    Future result = ApplicationManager.getApplication().runWriteAction(
      (ThrowableComputable<Future, Exception>)() -> ApplicationManager.getApplication().executeOnPooledThread(() -> {
        MavenServerManager.getInstance().shutdown(true);
        MavenServerManager.getInstance().getConnector(myProject, myProjectRoot.getPath());
      }));


    long start = System.currentTimeMillis();
    long end = TimeUnit.SECONDS.toMillis(10) + start;
    boolean ok = false;
    while (System.currentTimeMillis() < end) {
      EdtTestUtil.runInEdtAndWait(() -> {
        PlatformTestUtil.dispatchAllEventsInIdeEventQueue();
      });
      try {
        result.get(0, TimeUnit.MILLISECONDS);
        ok = true;
        break;
      }
      catch (InterruptedException | java.util.concurrent.ExecutionException e) {
        throw new RuntimeException(e);
      }
      catch (TimeoutException ignore) {
      }
    }
    if (!ok) {
      printThreadDump();
      fail();
    }
    result.cancel(true);
  }
  public void testConnectorRestartAfterVMChanged() {
    MavenWorkspaceSettingsComponent settingsComponent = MavenWorkspaceSettingsComponent.getInstance(myProject);
    String vmOptions = settingsComponent.getSettings().importingSettings.getVmOptionsForImporter();
    try {
      MavenServerConnector connector = MavenServerManager.getInstance().getConnector(myProject, myProjectRoot.getPath());
      settingsComponent.getSettings().importingSettings.setVmOptionsForImporter(vmOptions + " -DtestVm=test");
      assertNotSame(connector, MavenServerManager.getInstance().getConnector(myProject, myProjectRoot.getPath()));
    }
    finally {
      settingsComponent.getSettings().importingSettings.setVmOptionsForImporter(vmOptions);
    }
  }
}

@@ -1291,24 +1291,40 @@
 adlocks%0A    
+ensureConnected(
 MavenServerM
@@ -1392,16 +1392,17 @@
 tPath())
+)
 ;%0A%0A    F
@@ -1643,32 +1643,48 @@
 (true);%0A        
+ensureConnected(
 MavenServerManag
@@ -1740,32 +1740,33 @@
 tRoot.getPath())
+)
 ;%0A      %7D));%0A%0A%0A 
@@ -1930,16 +1930,23 @@
 () %3C end
+ && !ok
 ) %7B%0A    
@@ -2135,23 +2135,8 @@
 ue;%0A
-        break;%0A
     
@@ -2803,24 +2803,58 @@
 getPath());%0A
+      ensureConnected(connector);%0A
       settin
@@ -2983,16 +2983,32 @@
 nector, 
+ensureConnected(
 MavenSer
@@ -3077,24 +3077,25 @@
 .getPath()))
+)
 ;%0A    %7D%0A    
@@ -3205,11 +3205,557 @@
    %7D%0A  %7D
+%0A%0A  private MavenServerConnector ensureConnected(MavenServerConnector connector) %7B%0A    long timeout = TimeUnit.SECONDS.toMillis(10);%0A    long start = System.currentTimeMillis();%0A    while (connector.getState() == MavenServerConnector.State.STARTING) %7B%0A      if (System.currentTimeMillis() %3E start + timeout) %7B%0A        throw new RuntimeException(%22Server connector not connected in 10 seconds%22);%0A      %7D%0A      EdtTestUtil.runInEdtAndWait(() -%3E %7B%0A        PlatformTestUtil.dispatchAllEventsInIdeEventQueue();%0A      %7D);%0A    %7D%0A    return connector;%0A  %7D
 %0A%7D%0A

fix blinking maven tests