// 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.intellij.execution.actions;

import com.intellij.execution.ExecutionBundle;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.impl.RunDialog;
import com.intellij.execution.impl.RunManagerImpl;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.application.ApplicationManager;
import org.jetbrains.annotations.NotNull;

import java.util.List;

public class CreateAction extends BaseRunConfigurationAction {
  public CreateAction() {
    super(ExecutionBundle.lazyMessage("create.run.configuration.action.name"), Presentation.NULL_STRING, null);
  }

  @Override
  protected void perform(final ConfigurationContext context) {
    choosePolicy(context).perform(context);
  }

  @Override
  protected void updatePresentation(final Presentation presentation, @NotNull final String actionText, final ConfigurationContext context) {
    choosePolicy(context).update(presentation, context, actionText);
  }

  private static BaseCreatePolicy choosePolicy(final ConfigurationContext context) {
    final RunnerAndConfigurationSettings configuration = context.findExisting();
    return configuration == null ? Holder.CREATE_AND_EDIT : Holder.EDIT;
  }

  private static abstract class BaseCreatePolicy {
    public void update(final Presentation presentation, final ConfigurationContext context, @NotNull final String actionText) {
      updateText(presentation, actionText);
      updateIcon(presentation, context);
    }

    protected void updateIcon(final Presentation presentation, final ConfigurationContext context) {
      final List<ConfigurationFromContext> fromContext = context.getConfigurationsFromContext();
      if (fromContext != null && fromContext.size() == 1) {
        //hide fuzzy icon when multiple run configurations are possible
        presentation.setIcon(fromContext.iterator().next().getConfiguration().getIcon());
      }
    }

    protected abstract void updateText(final Presentation presentation, final String actionText);

    public abstract void perform(ConfigurationContext context);
  }

  private abstract static class CreatePolicy extends BaseCreatePolicy {
    @Override
    public void perform(final ConfigurationContext context) {
      RunManagerImpl runManager = (RunManagerImpl)context.getRunManager();
      RunnerAndConfigurationSettings configuration = context.getConfiguration();
      configuration.setShared(runManager.getConfigurationTemplate(configuration.getFactory()).isShared());
      runManager.addConfiguration(configuration);
      runManager.setSelectedConfiguration(configuration);
    }
  }

  private static class CreateAndEditPolicy extends CreatePolicy {
    @Override
    protected void updateText(final Presentation presentation, final String actionText) {
      presentation.setText(actionText.length() > 0 ? ExecutionBundle.message("create.run.configuration.for.item.action.name", actionText) + "..."
                                                   : ExecutionBundle.message("create.run.configuration.action.name"), false);
    }

    @Override
    public void perform(final ConfigurationContext context) {
      final RunnerAndConfigurationSettings configuration = context.getConfiguration();
      if (ApplicationManager.getApplication().isUnitTestMode() ||
          RunDialog.editConfiguration(context.getProject(), configuration,
                                      ExecutionBundle.message("create.run.configuration.for.item.dialog.title", configuration.getName()))) {
        final RunManagerImpl runManager = (RunManagerImpl)context.getRunManager();
        runManager.addConfiguration(configuration);
        runManager.setSelectedConfiguration(configuration);
      }
    }
  }

  private static class EditPolicy extends CreateAndEditPolicy {
    @Override
    protected void updateText(final Presentation presentation, final String actionText) {
      presentation.setText(actionText.length() > 0 ? ExecutionBundle.message("edit.run.configuration.for.item.action.name", actionText) + "..."
                                                   : ExecutionBundle.message("edit.run.configuration.action.name"), false);
    }

    @Override
    public void perform(final ConfigurationContext context) {
      final RunnerAndConfigurationSettings configuration = context.getConfiguration();
      if (!ApplicationManager.getApplication().isUnitTestMode()) {
        RunDialog.editConfiguration(context.getProject(), configuration,
                                    ExecutionBundle.message("edit.run.configuration.for.item.dialog.title", configuration.getName()));
      }
    }
  }

  private static class Holder {
    private static final BaseCreatePolicy CREATE_AND_EDIT = new CreateAndEditPolicy();
    private static final BaseCreatePolicy EDIT = new EditPolicy();
  }
}

@@ -17,10 +17,10 @@
 0-20
-18
+20
  Jet
@@ -2243,538 +2243,8 @@
  %7D%0A%0A
-  private abstract static class CreatePolicy extends BaseCreatePolicy %7B%0A    @Override%0A    public void perform(final ConfigurationContext context) %7B%0A      RunManagerImpl runManager = (RunManagerImpl)context.getRunManager();%0A      RunnerAndConfigurationSettings configuration = context.getConfiguration();%0A      configuration.setShared(runManager.getConfigurationTemplate(configuration.getFactory()).isShared());%0A      runManager.addConfiguration(configuration);%0A      runManager.setSelectedConfiguration(configuration);%0A    %7D%0A  %7D%0A%0A
   pr
@@ -2286,24 +2286,28 @@
 icy extends 
+Base
 CreatePolicy

remove unused com.intellij.execution.actions.CreateAction.CreatePolicy