/*
 * Copyright 2016 The Bazel Authors. All rights reserved.
 *
 * 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 com.google.idea.blaze.plugin.run;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import com.google.idea.blaze.base.command.BlazeCommand;
import com.google.idea.blaze.base.command.BlazeCommandName;
import com.google.idea.blaze.base.command.BlazeFlags;
import com.google.idea.blaze.base.ideinfo.JavaRuleIdeInfo;
import com.google.idea.blaze.base.ideinfo.LibraryArtifact;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.model.primitives.TargetExpression;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.run.BlazeConfigurationNameBuilder;
import com.google.idea.blaze.base.run.BlazeRunConfiguration;
import com.google.idea.blaze.base.run.rulefinder.RuleFinder;
import com.google.idea.blaze.base.settings.Blaze;
import com.google.idea.blaze.base.ui.UiUtil;
import com.google.idea.blaze.plugin.IntellijPluginRule;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.ConfigurationFactory;
import com.intellij.execution.configurations.JavaCommandLineState;
import com.intellij.execution.configurations.JavaParameters;
import com.intellij.execution.configurations.LocatableConfigurationBase;
import com.intellij.execution.configurations.ModuleRunConfiguration;
import com.intellij.execution.configurations.ParametersList;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.configurations.RuntimeConfigurationError;
import com.intellij.execution.configurations.RuntimeConfigurationException;
import com.intellij.execution.process.OSProcessHandler;
import com.intellij.execution.process.ProcessAdapter;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.openapi.application.JetBrainsProtocolHandler;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.roots.ui.configuration.JdkComboBox;
import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.LabeledComponent;
import com.intellij.openapi.util.BuildNumber;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.ui.ListCellRendererWrapper;
import com.intellij.ui.RawCommandLineEditor;
import com.intellij.util.PlatformUtils;
import com.intellij.util.execution.ParametersListUtil;
import java.awt.BorderLayout;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.Collection;
import java.util.List;
import javax.annotation.Nullable;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JTextArea;
import org.jdom.Element;

/**
 * A run configuration that builds a plugin jar via blaze, copies it to the SDK sandbox, then runs
 * IJ with the plugin loaded.
 */
public class BlazeIntellijPluginConfiguration extends LocatableConfigurationBase
    implements BlazeRunConfiguration, ModuleRunConfiguration {

  private static final String TARGET_TAG = "blaze-target";
  private static final String USER_BLAZE_FLAG_TAG = "blaze-user-flag";
  private static final String USER_EXE_FLAG_TAG = "blaze-user-exe-flag";
  private static final String SDK_ATTR = "blaze-plugin-sdk";
  private static final String VM_PARAMS_ATTR = "blaze-vm-params";
  private static final String PROGRAM_PARAMS_ATTR = "blaze-program-params";

  private final String buildSystem;

  @Nullable private Label target;
  private ImmutableList<String> blazeFlags = ImmutableList.of();
  private ImmutableList<String> exeFlags = ImmutableList.of();
  @Nullable private Sdk pluginSdk;
  @Nullable String vmParameters;
  @Nullable private String programParameters;

  public BlazeIntellijPluginConfiguration(
      Project project,
      ConfigurationFactory factory,
      String name,
      @Nullable RuleIdeInfo initialRule) {
    super(project, factory, name);
    this.buildSystem = Blaze.buildSystemName(project);
    Sdk projectSdk = ProjectRootManager.getInstance(project).getProjectSdk();
    if (IdeaJdkHelper.isIdeaJdk(projectSdk)) {
      pluginSdk = projectSdk;
    }
    if (initialRule != null) {
      target = initialRule.label;
    }
  }

  @Override
  @Nullable
  public Label getTarget() {
    return target;
  }

  public void setTarget(Label target) {
    this.target = target;
  }

  private ImmutableList<File> findPluginJars() throws ExecutionException {
    RuleIdeInfo rule = RuleFinder.getInstance().ruleForTarget(getProject(), getTarget());
    if (rule == null) {
      throw new ExecutionException(
          buildSystem + " rule '" + getTarget() + "' not imported during sync");
    }
    return IntellijPluginRule.isPluginBundle(rule)
        ? findBundledJars(rule)
        : ImmutableList.of(findPluginJar(rule));
  }

  private ImmutableList<File> findBundledJars(RuleIdeInfo rule) throws ExecutionException {
    ImmutableList.Builder<File> jars = ImmutableList.builder();
    for (Label dep : rule.dependencies) {
      RuleIdeInfo depRule = RuleFinder.getInstance().ruleForTarget(getProject(), dep);
      if (depRule != null && IntellijPluginRule.isSinglePluginRule(depRule)) {
        jars.add(findPluginJar(depRule));
      }
    }
    return jars.build();
  }

  private File findPluginJar(RuleIdeInfo rule) throws ExecutionException {
    JavaRuleIdeInfo javaRuleIdeInfo = rule.javaRuleIdeInfo;
    if (!IntellijPluginRule.isSinglePluginRule(rule) || javaRuleIdeInfo == null) {
      throw new ExecutionException(
          buildSystem + " rule '" + rule.label + "' is not a valid intellij_plugin rule");
    }
    Collection<LibraryArtifact> jars = javaRuleIdeInfo.jars;
    if (javaRuleIdeInfo.jars.size() > 1) {
      throw new ExecutionException("Invalid IntelliJ plugin rule: it has multiple output jars");
    }
    LibraryArtifact artifact = jars.isEmpty() ? null : jars.iterator().next();
    if (artifact == null || artifact.classJar == null) {
      throw new ExecutionException("No output plugin jar found for '" + rule.label + "'");
    }
    return artifact.classJar.getFile();
  }

  /**
   * Plugin jar has been previously created via blaze build. This method: - copies jar to sandbox
   * environment - cracks open jar and finds plugin.xml (with ID, etc., needed for JVM args) - sets
   * up the SDK, etc. (use project SDK?) - sets up the JVM, and returns a JavaCommandLineState
   */
  @Nullable
  @Override
  public RunProfileState getState(Executor executor, ExecutionEnvironment env)
      throws ExecutionException {
    final Sdk ideaJdk = pluginSdk;
    if (!IdeaJdkHelper.isIdeaJdk(ideaJdk)) {
      throw new ExecutionException("Choose an IntelliJ Platform Plugin SDK");
    }
    String sandboxHome = IdeaJdkHelper.getSandboxHome(ideaJdk);
    if (sandboxHome == null) {
      throw new ExecutionException("No sandbox specified for IntelliJ Platform Plugin SDK");
    }

    try {
      sandboxHome = new File(sandboxHome).getCanonicalPath();
    } catch (IOException e) {
      throw new ExecutionException("No sandbox specified for IntelliJ Platform Plugin SDK");
    }
    final String canonicalSandbox = sandboxHome;
    final ImmutableList<File> pluginJars = findPluginJars();
    for (File file : pluginJars) {
      if (!file.exists()) {
        throw new ExecutionException(
            String.format(
                "Plugin jar '%s' not found. Did the %s build fail?", file.getName(), buildSystem));
      }
    }
    // copy license from running instance of idea
    IdeaJdkHelper.copyIDEALicense(sandboxHome);

    final JavaCommandLineState state =
        new JavaCommandLineState(env) {
          @Override
          protected JavaParameters createJavaParameters() throws ExecutionException {
            String buildNumber = IdeaJdkHelper.getBuildNumber(ideaJdk);
            List<String> pluginIds = Lists.newArrayList();
            for (File jar : pluginJars) {
              pluginIds.add(copyPluginJarToSandbox(jar, buildNumber, canonicalSandbox));
            }

            final JavaParameters params = new JavaParameters();

            ParametersList vm = params.getVMParametersList();

            fillParameterList(vm, vmParameters);
            fillParameterList(params.getProgramParametersList(), programParameters);

            IntellijWithPluginClasspathHelper.addRequiredVmParams(params, ideaJdk);

            vm.defineProperty(
                JetBrainsProtocolHandler.REQUIRED_PLUGINS_KEY, Joiner.on(',').join(pluginIds));

            if (!vm.hasProperty(PlatformUtils.PLATFORM_PREFIX_KEY) && buildNumber != null) {
              String prefix = IdeaJdkHelper.getPlatformPrefix(buildNumber);
              if (prefix != null) {
                vm.defineProperty(PlatformUtils.PLATFORM_PREFIX_KEY, prefix);
              }
            }
            return params;
          }

          @Override
          protected OSProcessHandler startProcess() throws ExecutionException {
            final OSProcessHandler handler = super.startProcess();
            handler.addProcessListener(
                new ProcessAdapter() {
                  @Override
                  public void processTerminated(ProcessEvent event) {
                    for (File jar : pluginJars) {
                      pluginDestination(jar, canonicalSandbox).delete();
                    }
                  }
                });
            return handler;
          }
        };
    return state;
  }

  private static File pluginDestination(File jar, String sandboxPath) {
    return new File(sandboxPath, "plugins/" + jar.getName());
  }

  /** Copies the plugin jar to the sandbox, and returns the plugin ID. */
  private static String copyPluginJarToSandbox(File jar, String buildNumber, String sandboxPath)
      throws ExecutionException {
    IdeaPluginDescriptor pluginDescriptor = PluginManagerCore.loadDescriptor(jar, "plugin.xml");
    if (PluginManagerCore.isIncompatible(pluginDescriptor, BuildNumber.fromString(buildNumber))) {
      throw new ExecutionException(
          String.format(
              "Plugin SDK version '%s' is incompatible with this plugin "
                  + "(since: '%s', until: '%s')",
              buildNumber, pluginDescriptor.getSinceBuild(), pluginDescriptor.getUntilBuild()));
    }
    File pluginJarDestination = pluginDestination(jar, sandboxPath);
    try {
      pluginJarDestination.getParentFile().mkdirs();
      Files.copy(jar.toPath(), pluginJarDestination.toPath(), StandardCopyOption.REPLACE_EXISTING);
    } catch (IOException e) {
      throw new ExecutionException("Error copying plugin jar to sandbox", e);
    }
    return pluginDescriptor.getPluginId().getIdString();
  }

  private static void fillParameterList(ParametersList list, @Nullable String value) {
    if (value == null) {
      return;
    }

    for (String parameter : value.split(" ")) {
      if (parameter != null && parameter.length() > 0) {
        list.add(parameter);
      }
    }
  }

  @Override
  public Module[] getModules() {
    return Module.EMPTY_ARRAY;
  }

  @Override
  public void checkConfiguration() throws RuntimeConfigurationException {
    super.checkConfiguration();

    Label target = getTarget();
    if (target == null) {
      throw new RuntimeConfigurationError("Select a target to run");
    }
    RuleIdeInfo rule = RuleFinder.getInstance().ruleForTarget(getProject(), target);
    if (rule == null) {
      throw new RuntimeConfigurationError("The selected target does not exist.");
    }
    if (!IntellijPluginRule.isPluginRule(rule)) {
      throw new RuntimeConfigurationError("The selected target is not an intellij_plugin");
    }
    if (!IdeaJdkHelper.isIdeaJdk(pluginSdk)) {
      throw new RuntimeConfigurationError("Select an IntelliJ Platform Plugin SDK");
    }
  }

  @Override
  public void readExternal(Element element) throws InvalidDataException {
    super.readExternal(element);
    // Target is persisted as a tag to permit multiple targets in the future.
    Element targetElement = element.getChild(TARGET_TAG);
    if (targetElement != null && !Strings.isNullOrEmpty(targetElement.getTextTrim())) {
      target = (Label) TargetExpression.fromString(targetElement.getTextTrim());
    } else {
      target = null;
    }
    blazeFlags = loadUserFlags(element, USER_BLAZE_FLAG_TAG);
    exeFlags = loadUserFlags(element, USER_EXE_FLAG_TAG);

    String sdkName = element.getAttributeValue(SDK_ATTR);
    if (!Strings.isNullOrEmpty(sdkName)) {
      pluginSdk = ProjectJdkTable.getInstance().findJdk(sdkName);
    }
    vmParameters = Strings.emptyToNull(element.getAttributeValue(VM_PARAMS_ATTR));
    programParameters = Strings.emptyToNull(element.getAttributeValue(PROGRAM_PARAMS_ATTR));
  }

  private static ImmutableList<String> loadUserFlags(Element root, String tag) {
    ImmutableList.Builder<String> flagsBuilder = ImmutableList.builder();
    for (Element e : root.getChildren(tag)) {
      String flag = e.getTextTrim();
      if (flag != null && !flag.isEmpty()) {
        flagsBuilder.add(flag);
      }
    }
    return flagsBuilder.build();
  }

  private static void saveUserFlags(Element root, List<String> flags, String tag) {
    for (String flag : flags) {
      Element child = new Element(tag);
      child.setText(flag);
      root.addContent(child);
    }
  }

  @Override
  public void writeExternal(Element element) throws WriteExternalException {
    super.writeExternal(element);
    if (target != null) {
      // Target is persisted as a tag to permit multiple targets in the future.
      Element targetElement = new Element(TARGET_TAG);
      targetElement.setText(target.toString());
      element.addContent(targetElement);
    }
    saveUserFlags(element, blazeFlags, USER_BLAZE_FLAG_TAG);
    saveUserFlags(element, exeFlags, USER_EXE_FLAG_TAG);
    if (pluginSdk != null) {
      element.setAttribute(SDK_ATTR, pluginSdk.getName());
    }
    if (vmParameters != null) {
      element.setAttribute(VM_PARAMS_ATTR, vmParameters);
    }
    if (programParameters != null) {
      element.setAttribute(PROGRAM_PARAMS_ATTR, programParameters);
    }
  }

  @Override
  public BlazeIntellijPluginConfiguration clone() {
    final BlazeIntellijPluginConfiguration configuration =
        (BlazeIntellijPluginConfiguration) super.clone();
    configuration.target = target;
    configuration.blazeFlags = blazeFlags;
    configuration.exeFlags = exeFlags;
    configuration.pluginSdk = pluginSdk;
    configuration.vmParameters = vmParameters;
    configuration.programParameters = programParameters;
    return configuration;
  }

  protected BlazeCommand buildBlazeCommand(Project project, ProjectViewSet projectViewSet) {
    BlazeCommand.Builder command =
        BlazeCommand.builder(Blaze.getBuildSystem(getProject()), BlazeCommandName.BUILD)
            .addTargets(getTarget())
            .addBlazeFlags(BlazeFlags.buildFlags(project, projectViewSet))
            .addBlazeFlags(blazeFlags)
            .addExeFlags(exeFlags);
    return command.build();
  }

  @Override
  public BlazeIntellijPluginConfigurationSettingsEditor getConfigurationEditor() {
    List<RuleIdeInfo> javaRules =
        RuleFinder.getInstance().findRules(getProject(), IntellijPluginRule::isPluginRule);
    List<Label> javaLabels = Lists.newArrayList();
    for (RuleIdeInfo rule : javaRules) {
      javaLabels.add(rule.label);
    }
    return new BlazeIntellijPluginConfigurationSettingsEditor(buildSystem, javaLabels);
  }

  @Override
  @Nullable
  public String suggestedName() {
    Label target = getTarget();
    if (target == null) {
      return null;
    }
    return new BlazeConfigurationNameBuilder()
        .setBuildSystemName(getProject())
        .setCommandName("build")
        .setTargetString(target)
        .build();
  }

  @VisibleForTesting
  static class BlazeIntellijPluginConfigurationSettingsEditor
      extends SettingsEditor<BlazeIntellijPluginConfiguration> {
    private final String buildSystemName;
    private final ComboBox targetCombo;
    private final JTextArea blazeFlagsField = new JTextArea(5, 0);
    private final JTextArea exeFlagsField = new JTextArea(5, 0);
    private final JdkComboBox sdkCombo;
    private final LabeledComponent<RawCommandLineEditor> vmParameters = new LabeledComponent<>();
    private final LabeledComponent<RawCommandLineEditor> programParameters =
        new LabeledComponent<>();

    public BlazeIntellijPluginConfigurationSettingsEditor(
        String buildSystemName, List<Label> javaLabels) {
      this.buildSystemName = buildSystemName;
      targetCombo =
          new ComboBox(
              new DefaultComboBoxModel(Ordering.usingToString().sortedCopy(javaLabels).toArray()));
      targetCombo.setRenderer(
          new ListCellRendererWrapper<Label>() {
            @Override
            public void customize(
                JList list, @Nullable Label value, int index, boolean selected, boolean hasFocus) {
              setText(value == null ? null : value.toString());
            }
          });

      ProjectSdksModel sdksModel = new ProjectSdksModel();
      sdksModel.reset(null);
      sdkCombo = new JdkComboBox(sdksModel, IdeaJdkHelper::isIdeaJdkType);
    }

    @VisibleForTesting
    @Override
    public void resetEditorFrom(BlazeIntellijPluginConfiguration s) {
      targetCombo.setSelectedItem(s.getTarget());
      blazeFlagsField.setText(ParametersListUtil.join(s.blazeFlags));
      exeFlagsField.setText(ParametersListUtil.join(s.exeFlags));
      if (s.pluginSdk != null) {
        sdkCombo.setSelectedJdk(s.pluginSdk);
      } else {
        s.pluginSdk = sdkCombo.getSelectedJdk();
      }
      if (s.vmParameters != null) {
        vmParameters.getComponent().setText(s.vmParameters);
      }
      if (s.programParameters != null) {
        programParameters.getComponent().setText(s.programParameters);
      }
    }

    @VisibleForTesting
    @Override
    public void applyEditorTo(BlazeIntellijPluginConfiguration s) throws ConfigurationException {
      try {
        s.target = (Label) targetCombo.getSelectedItem();
      } catch (ClassCastException e) {
        throw new ConfigurationException("Invalid label specified.");
      }
      s.blazeFlags =
          ImmutableList.copyOf(
              ParametersListUtil.parse(Strings.nullToEmpty(blazeFlagsField.getText())));
      s.exeFlags =
          ImmutableList.copyOf(
              ParametersListUtil.parse(Strings.nullToEmpty(exeFlagsField.getText())));
      s.pluginSdk = sdkCombo.getSelectedJdk();
      s.vmParameters = vmParameters.getComponent().getText();
      s.programParameters = programParameters.getComponent().getText();
    }

    @Override
    protected JComponent createEditor() {
      vmParameters.setText("VM options:");
      vmParameters.setComponent(new RawCommandLineEditor());
      vmParameters.getComponent().setDialogCaption(vmParameters.getRawText());
      vmParameters.setLabelLocation(BorderLayout.WEST);

      programParameters.setText("Program arguments");
      programParameters.setComponent(new RawCommandLineEditor());
      programParameters.getComponent().setDialogCaption(programParameters.getRawText());
      programParameters.setLabelLocation(BorderLayout.WEST);

      return UiUtil.createBox(
          new JLabel("Target:"),
          targetCombo,
          new JLabel("Plugin SDK"),
          sdkCombo,
          vmParameters.getLabel(),
          vmParameters.getComponent(),
          programParameters.getLabel(),
          programParameters.getComponent(),
          new JLabel(buildSystemName + " flags:"),
          blazeFlagsField,
          new JLabel("Executable flags:"),
          exeFlagsField);
    }
  }
}
