/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.management.internal.cli.commands;

import static org.apache.geode.management.internal.cli.i18n.CliStrings.GROUP;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Properties;
import java.util.Set;

import joptsimple.internal.Strings;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.Logger;
import org.springframework.shell.core.annotation.CliCommand;
import org.springframework.shell.core.annotation.CliOption;

import org.apache.geode.distributed.ConfigurationPersistenceService;
import org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
import org.apache.geode.logging.internal.log4j.api.LogService;
import org.apache.geode.management.cli.CliMetaData;
import org.apache.geode.management.cli.GfshCommand;
import org.apache.geode.management.cli.Result;
import org.apache.geode.management.internal.cli.AbstractCliAroundInterceptor;
import org.apache.geode.management.internal.cli.GfshParseResult;
import org.apache.geode.management.internal.cli.i18n.CliStrings;
import org.apache.geode.management.internal.cli.result.model.DataResultModel;
import org.apache.geode.management.internal.cli.result.model.FileResultModel;
import org.apache.geode.management.internal.cli.result.model.InfoResultModel;
import org.apache.geode.management.internal.cli.result.model.ResultModel;
import org.apache.geode.management.internal.configuration.domain.Configuration;
import org.apache.geode.management.internal.configuration.utils.ZipUtils;
import org.apache.geode.management.internal.security.ResourceOperation;
import org.apache.geode.security.ResourcePermission.Operation;
import org.apache.geode.security.ResourcePermission.Resource;

/**
 * Commands for the cluster configuration
 */
@SuppressWarnings("unused")
public class ExportClusterConfigurationCommand extends GfshCommand {
  private static final Logger logger = LogService.getLogger();
  public static final String XML_FILE = "xml-file";

  @CliCommand(value = {CliStrings.EXPORT_SHARED_CONFIG},
      help = CliStrings.EXPORT_SHARED_CONFIG__HELP)
  @CliMetaData(
      interceptor = "org.apache.geode.management.internal.cli.commands.ExportClusterConfigurationCommand$ExportInterceptor",
      relatedTopic = {CliStrings.TOPIC_GEODE_CONFIG})
  @ResourceOperation(resource = Resource.CLUSTER, operation = Operation.READ)
  public ResultModel exportSharedConfig(
      @CliOption(key = GROUP,
          specifiedDefaultValue = ConfigurationPersistenceService.CLUSTER_CONFIG,
          unspecifiedDefaultValue = ConfigurationPersistenceService.CLUSTER_CONFIG) String group,
      @CliOption(key = XML_FILE) String xmlFile,
      @CliOption(key = CliStrings.EXPORT_SHARED_CONFIG__FILE,
          help = CliStrings.EXPORT_SHARED_CONFIG__FILE__HELP) String zipFileName)
      throws IOException {

    if (!isSharedConfigurationRunning()) {
      return ResultModel.createError("Cluster configuration service is not running.");
    }

    ResultModel result = new ResultModel();
    InternalConfigurationPersistenceService configPersistenceService =
        (InternalConfigurationPersistenceService) getConfigurationPersistenceService();
    if (zipFileName != null) {
      Path tempDir = Files.createTempDirectory("temp");
      Path exportedDir = tempDir.resolve("cluster_config");
      Path zipFile = tempDir.resolve(FilenameUtils.getName(zipFileName));
      try {
        for (Configuration config : configPersistenceService.getEntireConfiguration().values()) {
          configPersistenceService.writeConfigToFile(config, exportedDir.toFile());
        }
        ZipUtils.zipDirectory(exportedDir, zipFile);
        result.addFile(zipFile.toFile(), FileResultModel.FILE_TYPE_BINARY);
      } catch (Exception e) {
        logger.error("unable to export configuration.", e);
      } finally {
        FileUtils.deleteQuietly(tempDir.toFile());
      }
    } else {
      Configuration configuration = configPersistenceService.getConfiguration(group);
      if (configuration == null) {
        return ResultModel.createError("No cluster configuration for '" + group + "'.");
      }

      String cacheXmlContent = configuration.getCacheXmlContent();
      if (cacheXmlContent != null) {
        InfoResultModel xmlSection = result.addInfo("xml");
        xmlSection.setHeader(configuration.getCacheXmlFileName() + ": ");
        xmlSection.addLine(cacheXmlContent);
      }

      Properties gemfireProperties = configuration.getGemfireProperties();
      if (gemfireProperties.size() > 0) {
        DataResultModel propertySection = result.addData("properties");
        propertySection.setHeader("Properties: ");
        propertySection.addData(gemfireProperties);
      }

      Set<String> jarNames = configuration.getJarNames();
      if (jarNames.size() > 0) {
        InfoResultModel jarSection = result.addInfo("jars");
        jarSection.setHeader("Jars: ");
        jarSection.addLine(Strings.join(jarNames, ", "));
      }
    }

    return result;
  }

  /**
   * Interceptor used by gfsh to intercept execution of export shared config command at "shell".
   */
  public static class ExportInterceptor extends AbstractCliAroundInterceptor {
    private String saveDirString;
    private static final Logger logger = LogService.getLogger();

    @Override
    public ResultModel preExecution(GfshParseResult parseResult) {
      String zip = parseResult.getParamValueAsString(CliStrings.EXPORT_SHARED_CONFIG__FILE);
      String xmlFile = parseResult.getParamValueAsString(XML_FILE);
      String group = parseResult.getParamValueAsString(GROUP);

      if (group != null && group.contains(",")) {
        return ResultModel.createError("Only a single group name is supported.");
      }

      if (zip != null && xmlFile != null) {
        return ResultModel.createError("Zip file and xml File can't both be specified.");
      }

      if (zip != null && !group.equals(ConfigurationPersistenceService.CLUSTER_CONFIG)) {
        return ResultModel.createError("zip file can not be exported with a specific group.");
      }

      if (zip != null && !zip.endsWith(".zip")) {
        return ResultModel
            .createError(CliStrings.format(CliStrings.INVALID_FILE_EXTENSION, ".zip"));
      }

      String exportedFile = (zip != null) ? zip : xmlFile;
      if (exportedFile != null) {
        // make sure the file does not exist so that we don't overwrite some existing file
        File file = new File(exportedFile).getAbsoluteFile();
        if (file.exists()) {
          String message = file.getAbsolutePath() + " already exists. Overwrite it? ";
          if (readYesNo(message, Response.YES) == Response.NO) {
            return ResultModel.createError("Aborted. " + exportedFile + "already exists.");
          }
        }
      }

      return ResultModel.createInfo("");
    }

    @Override
    public ResultModel postExecution(GfshParseResult parseResult, ResultModel result, Path tempFile)
        throws IOException {
      if (result.getStatus() == Result.Status.ERROR) {
        return result;
      }
      String xmlFile = parseResult.getParamValueAsString(XML_FILE);
      String zipFile = parseResult.getParamValueAsString(CliStrings.EXPORT_SHARED_CONFIG__FILE);
      String group = parseResult.getParamValueAsString(GROUP);
      // save the result to the file
      if (xmlFile != null) {
        InfoResultModel xmlSection = result.getInfoSection("xml");
        if (xmlSection == null) {
          InfoResultModel info = result.addInfo("info");
          info.addLine(String.format("xml content is empty. %s is not created.", xmlFile));
        } else {
          File file = new File(xmlFile).getAbsoluteFile();
          FileUtils.write(file, Strings.join(xmlSection.getContent(), System.lineSeparator()),
              Charset.defaultCharset());
          xmlSection.removeLine(0);
          xmlSection.addLine("xml content exported to " + file.getAbsolutePath());
        }
      } else if (zipFile != null) {
        // delete the existing file since at this point, user is OK to replace the old zip.
        File file = new File(zipFile).getAbsoluteFile();
        if (file.exists()) {
          FileUtils.deleteQuietly(file);
        }
        result.saveFileTo(file.getParentFile());
      }
      return result;
    }
  }
}
