/*
 * 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.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);
    settings.readExternal(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;
  }
}
