/*
 * 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.session.tests;

import static java.lang.System.lineSeparator;
import static java.nio.charset.Charset.defaultCharset;
import static org.apache.commons.io.FileUtils.readLines;
import static org.apache.geode.session.tests.ContainerInstall.GEODE_BUILD_HOME;
import static org.apache.geode.session.tests.ContainerInstall.TMP_DIR;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.IntSupplier;

import org.junit.Assume;

/**
 * Container for a generic app server
 *
 * Extends {@link ServerContainer} to form a basic container which sets up a GenericAppServer
 * container. Currently being used solely for Jetty 9 containers.
 *
 * The container modifies a copy of the session testing war using the modify_war_file script in
 * order to properly implement geode session replication for generic application servers. That means
 * that tests using this container will only run on linux.
 *
 * In theory, adding support for additional containers should just be a matter of changing the
 * {@link GenericAppServerInstall} to support other installations, since this container does not
 * depend upon the type of appserver in any way.
 */
public class GenericAppServerContainer extends ServerContainer {
  private final File modifyWarScript;
  private final File modifyWarScriptLog;

  private static final String DEFAULT_GENERIC_APPSERVER_WAR_DIR = TMP_DIR + "/cargo_wars/";

  /**
   * Setup the generic appserver container
   *
   * Sets up a configuration for the container using the specified installation and configuration
   * home. Finds the script needed to modify the war file, sets up the new WAR file to modify by
   * creating a temporary WAR file to use, deploys the war to the Cargo container, and sets various
   * container properties (i.e. locator, local cache, etc.)
   */
  public GenericAppServerContainer(GenericAppServerInstall install, File containerConfigHome,
      String containerDescriptors, IntSupplier portSupplier) throws IOException {
    super(install, containerConfigHome, containerDescriptors, portSupplier);

    // Setup modify war script file so that it is executable and easily findable
    modifyWarScript = new File(install.getModulePath() + "/bin/modify_war");
    modifyWarScript.setExecutable(true);

    // Setup modify_war script logging file
    modifyWarScriptLog = new File(cargoLogDir + "/warScript.log");
    modifyWarScriptLog.createNewFile();

    // Ignore tests that are running on windows, since they can't run the modify war script
    Assume.assumeFalse(System.getProperty("os.name").toLowerCase().contains("win"));

    // Create temp war file to use
    File warDir = new File(DEFAULT_GENERIC_APPSERVER_WAR_DIR);
    warDir.mkdirs();
    setWarFile(File.createTempFile(description, ".war", warDir));

    // Deploy war file to container configuration
    deployWar();
    // Setup the default installations locators
    setLocator(install.getDefaultLocatorAddress(), install.getDefaultLocatorPort());

    // Make sure that local caches are disabled by default
    setCacheProperty("enable_local_cache",
        Boolean.toString(install.getConnectionType().enableLocalCache()));
  }

  /**
   * Builds the command needed to run the {@link #modifyWarScript}
   *
   * The command is built as an array list of strings with each element representing a string
   * separated by a space on the command line. For example, the list {'-t', 'geode'} would represent
   * 'modify_war -t geode' on the command line.
   *
   * The command built points towards the {@link ContainerInstall#getWarFilePath()} as the starting
   * file and the {@link #warFile} as the output file. Cache and system properties are specified
   * when modifying the WAR, so the elements contained within the {@link #cacheProperties} and
   * {@link #systemProperties} maps are also added to the command built.
   */
  private List<String> buildCommand() throws IOException {
    ContainerInstall install = getInstall();

    // Start command list
    List<String> command = new ArrayList<>();
    // Path to the modify war script to run
    command.add(modifyWarScript.getAbsolutePath());
    // Path to the WAR file to modify
    command.add("-w");
    command.add(install.getWarFilePath());
    // Get connection type for the WAR (peer-to-peer or client-server)
    command.add("-t");
    command.add(install.getConnectionType().getName());
    // Path to the modified version of the origin WAR file
    command.add("-o");
    command.add(getWarFile().getAbsolutePath());
    // Add all the cache properties setup to the WAR file
    for (String property : cacheProperties.keySet()) {
      command.add("-p");
      command.add("gemfire.cache." + property + "=" + getCacheProperty(property));
    }
    // Add all the system properties to the WAR file
    for (String property : systemProperties.keySet()) {
      command.add("-p");
      command.add("gemfire.property." + property + "=" + getSystemProperty(property));
    }

    return command;
  }

  /**
   * Modifies the {@link ContainerInstall#getWarFilePath()} for container use, by simulating a
   * command line execution of the modify_war_file script using the commands built from
   * {@link #buildCommand()}
   *
   * The modified WAR file is sent to {@link #warFile}.
   *
   * @throws IOException If the command executed returns with a non-zero exit code.
   */
  private void modifyWarFile() throws IOException, InterruptedException {
    // Build the environment to run the command
    ProcessBuilder builder = new ProcessBuilder();
    builder.environment().put("GEODE", GEODE_BUILD_HOME);
    builder.inheritIO();
    // Setup the environment builder with the command
    builder.command(buildCommand());
    // Redirect the command line logging to a file

    builder.redirectError(modifyWarScriptLog);
    builder.redirectOutput(modifyWarScriptLog);
    logger.info("Running command: " + String.join(" ", builder.command()));

    // Run the command
    Process process = builder.start();

    // Wait for the command to finish
    int exitCode = process.waitFor();
    // Throw error if bad exit
    if (exitCode != 0) {
      StringBuilder sb = new StringBuilder();
      sb.append("Unable to run modify_war script, command: ").append(builder.command());
      sb.append(lineSeparator());
      sb.append("check log file: ");
      for (String line : readLines(modifyWarScriptLog, defaultCharset())) {
        sb.append(lineSeparator());
        sb.append(line);
      }
      throw new IOException(sb.toString());
    }
  }

  /**
   * Update the container's settings by calling {@link #modifyWarFile()} method
   */
  @Override
  public void writeSettings() throws Exception {
    modifyWarFile();
  }
}
