// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.jetbrains.rest.run;

import com.intellij.execution.ExecutionException;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.configurations.ParametersList;
import com.intellij.execution.configurations.ParamsGroup;
import com.intellij.execution.process.ProcessAdapter;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.TransactionGuard;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.python.HelperPackage;
import com.jetbrains.python.run.PythonCommandLineState;
import com.jetbrains.python.run.PythonProcessRunner;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * User : catherine
 */
public abstract class RestCommandLineState extends PythonCommandLineState {
  protected final RestRunConfiguration myConfiguration;

  public RestCommandLineState(RestRunConfiguration configuration,
                              ExecutionEnvironment env) {
    super(configuration, env);
    myConfiguration = configuration;
  }

  @Override
  protected void buildCommandLineParameters(GeneralCommandLine commandLine) {
    ParametersList parametersList = commandLine.getParametersList();
    ParamsGroup exeOptions = parametersList.getParamsGroup(GROUP_EXE_OPTIONS);
    assert exeOptions != null;
    exeOptions.addParametersString(myConfiguration.getInterpreterOptions());

    ParamsGroup scriptParameters = parametersList.getParamsGroup(GROUP_SCRIPT);
    assert scriptParameters != null;
    getRunner().addToGroup(scriptParameters, commandLine);
    final String key = getKey();
    if (key != null)
      scriptParameters.addParameter(key);
    scriptParameters.addParameter(getTask());

    final String params = myConfiguration.getParams();
    if (params != null) scriptParameters.addParametersString(params);

    if (!StringUtil.isEmptyOrSpaces(myConfiguration.getInputFile()))
      scriptParameters.addParameter(myConfiguration.getInputFile());

    if (!StringUtil.isEmptyOrSpaces(myConfiguration.getOutputFile()))
      scriptParameters.addParameter(myConfiguration.getOutputFile());

    if (!StringUtil.isEmptyOrSpaces(myConfiguration.getWorkingDirectory()))
      commandLine.setWorkDirectory(myConfiguration.getWorkingDirectory());
  }

  @Override
  protected ProcessHandler doCreateProcess(GeneralCommandLine commandLine) throws ExecutionException {
    final Runnable afterTask = getAfterTask();
    ProcessHandler processHandler = PythonProcessRunner.createProcess(commandLine, false);
    if (afterTask != null) {
      processHandler.addProcessListener(new ProcessAdapter() {
                                            @Override
                                            public void processTerminated(@NotNull ProcessEvent event) {
                                              TransactionGuard.getInstance().submitTransactionLater(ApplicationManager.getApplication(), afterTask);
                                            }});
    }
    return processHandler;
  }

  @Nullable
  protected Runnable getAfterTask() {
    return null;
  }

  @Nullable
  protected VirtualFile findOutput() {
    if (!StringUtil.isEmptyOrSpaces(myConfiguration.getOutputFile())) {
      VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(
        myConfiguration.getOutputFile());
      if (virtualFile == null) {
        virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(
          myConfiguration.getWorkingDirectory() + myConfiguration.getOutputFile());
      }
      return virtualFile;
    }
    return null;
  }

  protected abstract HelperPackage getRunner();

  protected abstract String getTask();

  @Nullable
  protected abstract String getKey();
}

@@ -685,66 +685,8 @@
 er;%0A
-import com.intellij.openapi.application.TransactionGuard;%0A
 impo
@@ -3203,62 +3203,8 @@
     
-TransactionGuard.getInstance().submitTransactionLater(
 Appl
@@ -3234,18 +3234,29 @@
 cation()
-, 
+.invokeLater(
 afterTas

replace deprecated transactions with invokeLater