/*
 * 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.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.TargetIdeInfo;
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.state.RunConfigurationFlagsState;
import com.google.idea.blaze.base.run.state.RunConfigurationStateEditor;
import com.google.idea.blaze.base.run.targetfinder.TargetFinder;
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.LogFileOptions;
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.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.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.ui.ListCellRendererWrapper;
import com.intellij.ui.RawCommandLineEditor;
import com.intellij.ui.components.JBCheckBox;
import com.intellij.util.PlatformUtils;
import java.awt.BorderLayout;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
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 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 static final String KEEP_IN_SYNC_TAG = "keep-in-sync";

  private final String buildSystem;

  @Nullable private Label target;
  private final RunConfigurationFlagsState blazeFlags;
  private final RunConfigurationFlagsState exeFlags;
  @Nullable private Sdk pluginSdk;
  @Nullable String vmParameters;
  @Nullable private String programParameters;

  // for keeping imported configurations in sync with their source XML
  @Nullable private Boolean keepInSync = null;

  public BlazeIntellijPluginConfiguration(
      Project project,
      ConfigurationFactory factory,
      String name,
      @Nullable TargetIdeInfo initialTarget) {
    super(project, factory, name);
    this.buildSystem = Blaze.buildSystemName(project);
    Sdk projectSdk = ProjectRootManager.getInstance(project).getProjectSdk();
    if (IdeaJdkHelper.isIdeaJdk(projectSdk)) {
      pluginSdk = projectSdk;
    }
    if (initialTarget != null) {
      target = initialTarget.key.label;
    }
    blazeFlags = new RunConfigurationFlagsState(USER_BLAZE_FLAG_TAG, buildSystem + " flags:");
    exeFlags = new RunConfigurationFlagsState(USER_EXE_FLAG_TAG, "Executable flags:");
  }

  @Override
  public void setKeepInSync(@Nullable Boolean keepInSync) {
    this.keepInSync = keepInSync;
  }

  @Override
  @Nullable
  public Boolean getKeepInSync() {
    return keepInSync;
  }

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

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

  public void setPluginSdk(Sdk sdk) {
    if (IdeaJdkHelper.isIdeaJdk(sdk)) {
      pluginSdk = sdk;
    }
  }

  @Override
  public ArrayList<LogFileOptions> getAllLogFiles() {
    ArrayList<LogFileOptions> result = new ArrayList<>();
    if (pluginSdk == null) {
      return result;
    }
    String sandboxHome = IdeaJdkHelper.getSandboxHome(pluginSdk);
    String logFile = Paths.get(sandboxHome, "system", "log", "idea.log").toString();
    LogFileOptions logFileOptions = new LogFileOptions("idea.log", logFile, true, true, true);
    result.add(logFileOptions);
    return result;
  }

  /**
   * 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");
    }
    String buildNumber = IdeaJdkHelper.getBuildNumber(ideaJdk);
    final BlazeIntellijPluginDeployer deployer =
        new BlazeIntellijPluginDeployer(getProject(), sandboxHome, buildNumber);
    deployer.addTarget(getTarget());

    // copy license from running instance of idea
    IdeaJdkHelper.copyIDEALicense(sandboxHome);

    final JavaCommandLineState state =
        new JavaCommandLineState(env) {
          @Override
          protected JavaParameters createJavaParameters() throws ExecutionException {
            List<String> pluginIds = deployer.deploy();

            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) {
                    deployer.deleteDeployment();
                  }
                });
            return handler;
          }
        };
    return state;
  }

  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 label = getTarget();
    if (label == null) {
      throw new RuntimeConfigurationError("Select a target to run");
    }
    TargetIdeInfo target = TargetFinder.getInstance().targetForLabel(getProject(), label);
    if (target == null) {
      throw new RuntimeConfigurationError("The selected target does not exist.");
    }
    if (!IntellijPluginRule.isPluginTarget(target)) {
      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.readExternal(element);
    exeFlags.readExternal(element);

    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));

    String keepInSyncString = element.getAttributeValue(KEEP_IN_SYNC_TAG);
    keepInSync = keepInSyncString != null ? Boolean.parseBoolean(keepInSyncString) : null;
  }

  @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);
    }
    blazeFlags.writeExternal(element);
    exeFlags.writeExternal(element);
    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);
    }
    if (keepInSync != null) {
      element.setAttribute(KEEP_IN_SYNC_TAG, Boolean.toString(keepInSync));
    }
  }

  @Override
  public BlazeIntellijPluginConfiguration clone() {
    final BlazeIntellijPluginConfiguration configuration =
        (BlazeIntellijPluginConfiguration) super.clone();
    configuration.target = target;
    configuration.blazeFlags.setFlags(blazeFlags.getFlags());
    configuration.exeFlags.setFlags(exeFlags.getFlags());
    configuration.pluginSdk = pluginSdk;
    configuration.vmParameters = vmParameters;
    configuration.programParameters = programParameters;
    configuration.keepInSync = keepInSync;
    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.getFlags())
            .addExeFlags(exeFlags.getFlags());
    return command.build();
  }

  @Override
  public BlazeIntellijPluginConfigurationSettingsEditor getConfigurationEditor() {
    List<TargetIdeInfo> javaTargets =
        TargetFinder.getInstance().findTargets(getProject(), IntellijPluginRule::isPluginTarget);
    List<Label> javaLabels = Lists.newArrayList();
    for (TargetIdeInfo target : javaTargets) {
      javaLabels.add(target.key.label);
    }
    return new BlazeIntellijPluginConfigurationSettingsEditor(
        javaLabels, blazeFlags.getEditor(getProject()), exeFlags.getEditor(getProject()));
  }

  @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 ComboBox<Label> targetCombo;
    private final RunConfigurationStateEditor blazeFlagsEditor;
    private final RunConfigurationStateEditor exeFlagsEditor;
    private final JdkComboBox sdkCombo;
    private final LabeledComponent<RawCommandLineEditor> vmParameters = new LabeledComponent<>();
    private final LabeledComponent<RawCommandLineEditor> programParameters =
        new LabeledComponent<>();
    private final JBCheckBox keepInSyncCheckBox;

    public BlazeIntellijPluginConfigurationSettingsEditor(
        List<Label> javaLabels,
        RunConfigurationStateEditor blazeFlagsEditor,
        RunConfigurationStateEditor exeFlagsEditor) {
      targetCombo =
          new ComboBox<>(
              new DefaultComboBoxModel<>(
                  Ordering.usingToString().sortedCopy(javaLabels).toArray(new Label[0])));
      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());
            }
          });
      this.blazeFlagsEditor = blazeFlagsEditor;
      this.exeFlagsEditor = exeFlagsEditor;
      ProjectSdksModel sdksModel = new ProjectSdksModel();
      sdksModel.reset(null);
      sdkCombo = new JdkComboBox(sdksModel, IdeaJdkHelper::isIdeaJdkType);

      keepInSyncCheckBox = new JBCheckBox("Keep in sync with source XML");
      keepInSyncCheckBox.addItemListener(e -> updateEnabledStatus());
    }

    private void updateEnabledStatus() {
      setEnabled(!keepInSyncCheckBox.isVisible() || !keepInSyncCheckBox.isSelected());
    }

    private void setEnabled(boolean enabled) {
      targetCombo.setEnabled(enabled);
      sdkCombo.setEnabled(enabled);
      vmParameters.getComponent().setEnabled(enabled);
      programParameters.getComponent().setEnabled(enabled);
      blazeFlagsEditor.setComponentEnabled(enabled);
      exeFlagsEditor.setComponentEnabled(enabled);
    }

    @VisibleForTesting
    @Override
    public void resetEditorFrom(BlazeIntellijPluginConfiguration s) {
      targetCombo.setSelectedItem(s.getTarget());
      blazeFlagsEditor.resetEditorFrom(s.blazeFlags);
      exeFlagsEditor.resetEditorFrom(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);
      }
      keepInSyncCheckBox.setVisible(s.keepInSync != null);
      if (s.keepInSync != null) {
        keepInSyncCheckBox.setSelected(s.keepInSync);
      }
    }

    @VisibleForTesting
    @Override
    public void applyEditorTo(BlazeIntellijPluginConfiguration s) throws ConfigurationException {
      try {
        s.target = (Label) targetCombo.getSelectedItem();
      } catch (ClassCastException e) {
        throw new ConfigurationException("Invalid label specified.");
      }
      blazeFlagsEditor.applyEditorTo(s.blazeFlags);
      exeFlagsEditor.applyEditorTo(s.exeFlags);
      s.pluginSdk = sdkCombo.getSelectedJdk();
      s.vmParameters = vmParameters.getComponent().getText();
      s.programParameters = programParameters.getComponent().getText();
      s.keepInSync = keepInSyncCheckBox.isVisible() ? keepInSyncCheckBox.isSelected() : null;
    }

    @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(),
          blazeFlagsEditor.createComponent(),
          exeFlagsEditor.createComponent(),
          keepInSyncCheckBox);
    }
  }
}
