/*
 * 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.base.run.exporter;

import com.google.common.annotations.VisibleForTesting;
import com.google.idea.blaze.base.run.BlazeRunConfiguration;
import com.google.idea.sdkcompat.run.RunnerAndConfigurationSettingsCompatUtils;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.impl.RunManagerImpl;
import com.intellij.execution.impl.RunnerAndConfigurationSettingsImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.WriteExternalException;
import java.io.File;
import java.io.IOException;
import javax.annotation.Nullable;
import org.jdom.Element;
import org.jdom.JDOMException;

/** Utility methods for converting run configuration to/from XML. */
public class RunConfigurationSerializer {

  private static final Logger logger = Logger.getInstance(RunConfigurationSerializer.class);

  public static Element writeToXml(RunConfiguration configuration) {
    RunnerAndConfigurationSettings settings =
        RunManagerImpl.getInstanceImpl(configuration.getProject()).getSettings(configuration);
    Element element = new Element("configuration");
    try {
      ((RunnerAndConfigurationSettingsImpl) settings).writeExternal(element);
    } catch (WriteExternalException e) {
      logger.warn("Error serializing run configuration to XML", e);
    }
    return element;
  }

  /**
   * Parses a RunConfiguration from the given XML file, and adds it to the project, if there's not
   * already a run configuration with the same name and type,
   */
  public static void loadFromXmlIgnoreExisting(Project project, File xmlFile) {
    try {
      loadFromXmlElementIgnoreExisting(project, JDOMUtil.load(xmlFile));
    } catch (InvalidDataException | JDOMException | IOException e) {
      logger.warn("Error parsing run configuration from XML", e);
    }
  }

  /**
   * Parses a RunConfiguration from the given XML element, and adds it to the project, if there's
   * not already a run configuration with the same name and type,
   */
  @VisibleForTesting
  static void loadFromXmlElementIgnoreExisting(Project project, Element element)
      throws InvalidDataException {
    if (!shouldLoadConfiguration(project, element)) {
      return;
    }
    RunnerAndConfigurationSettings settings =
        RunManagerImpl.getInstanceImpl(project).loadConfiguration(element, false);
    RunConfiguration config = settings != null ? settings.getConfiguration() : null;
    if (config instanceof BlazeRunConfiguration) {
      ((BlazeRunConfiguration) config).setKeepInSync(true);
    }
  }

  /**
   * Deserializes the configuration represented by the given XML element, then searches for an
   * existing run configuration in the project with the same name and type.
   */
  @Nullable
  @VisibleForTesting
  static RunnerAndConfigurationSettings findExisting(Project project, Element element)
      throws InvalidDataException {
    RunManagerImpl manager = RunManagerImpl.getInstanceImpl(project);
    RunnerAndConfigurationSettingsImpl settings = new RunnerAndConfigurationSettingsImpl(manager);
    RunnerAndConfigurationSettingsCompatUtils.readConfiguration(settings, element);
    RunConfiguration config = settings.getConfiguration();
    if (config == null) {
      return null;
    }
    return manager.findConfigurationByTypeAndName(config.getType().getId(), config.getName());
  }

  /**
   * Returns true if there's either no matching configuration altready in the project, or the
   * matching configuration is marked as 'keep in sync'.
   */
  @VisibleForTesting
  static boolean shouldLoadConfiguration(Project project, Element element)
      throws InvalidDataException {
    RunnerAndConfigurationSettings existing = findExisting(project, element);
    if (existing == null) {
      return true;
    }
    RunConfiguration config = existing.getConfiguration();
    if (!(config instanceof BlazeRunConfiguration)) {
      return false;
    }
    BlazeRunConfiguration blazeConfig = (BlazeRunConfiguration) config;
    Boolean keepInSync = blazeConfig.getKeepInSync();
    if (keepInSync == null) {
      // if the matching configuration was never previously imported, don't overwrite, but activate
      // the UI option to keep it in sync.
      blazeConfig.setKeepInSync(false);
      return false;
    }
    return keepInSync;
  }
}
