package com.jetbrains.python.run;

import com.intellij.execution.ExecutionException;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.process.ProcessTerminatedListener;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.ui.Messages;
import com.intellij.util.PathMappingSettings;
import com.jetbrains.python.remote.PyRemoteSdkAdditionalData;
import com.jetbrains.python.remote.PythonRemoteInterpreterManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * @author traff
 */
public class PyRemoteProcessStarter {
  public ProcessHandler startRemoteProcess(@NotNull Sdk sdk, @NotNull GeneralCommandLine commandLine, @Nullable Project project, @Nullable PathMappingSettings mappingSettings)
    throws ExecutionException {
    PythonRemoteInterpreterManager manager = PythonRemoteInterpreterManager.getInstance();
    if (manager != null) {
      ProcessHandler processHandler;

      while (true) {
        try {
          processHandler = doStartRemoteProcess(sdk, commandLine, manager, project, mappingSettings);
          break;
        }
        catch (ExecutionException e) {
          if (Messages.showYesNoDialog(e.getMessage() + "\nTry again?", "Can't Run Remote Interpreter", Messages.getErrorIcon()) ==
              Messages.NO) {
            throw new ExecutionException("Can't run remote python interpreter: " + e.getMessage());
          }
        }
      }
      ProcessTerminatedListener.attach(processHandler);
      return processHandler;
    }
    else {
      throw new PythonRemoteInterpreterManager.PyRemoteInterpreterExecutionException();
    }
  }

  protected ProcessHandler doStartRemoteProcess(@NotNull Sdk sdk,
                                                @NotNull GeneralCommandLine commandLine,
                                                @NotNull PythonRemoteInterpreterManager manager,
                                                @Nullable Project project,
                                                @Nullable PathMappingSettings settings)
    throws ExecutionException {

    return manager.startRemoteProcess(project, (PyRemoteSdkAdditionalData)sdk.getSdkAdditionalData(), commandLine,
                                      settings);
  }
}

@@ -258,24 +258,137 @@
 edListener;%0A
+import com.intellij.openapi.application.Application;%0Aimport com.intellij.openapi.application.ApplicationManager;%0A
 import com.i
@@ -420,16 +420,16 @@
 roject;%0A
-
 import c
@@ -895,76 +895,205 @@
 sdk,
- @NotNull GeneralCommandLine commandLine, @Nullable Project project,
+%0A                                           @NotNull GeneralCommandLine commandLine,%0A                                           @Nullable Project project,%0A                                          
  @Nu
@@ -1480,32 +1480,32 @@
 reak;%0A        %7D%0A
-
         catch (E
@@ -1523,24 +1523,268 @@
 eption e) %7B%0A
+          final Application application = ApplicationManager.getApplication();%0A          if (application != null && (application.isUnitTestMode() %7C%7C application.isHeadlessEnvironment())) %7B%0A            throw new RuntimeException(e);%0A          %7D%0A
           if

Throw exception with stacktrace if couldn't run remote process instead of message.