/*
 * 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 org.apache.geode.session.tests.ContainerInstall.TMP_DIR;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.HashMap;
import java.util.UUID;
import java.util.function.IntSupplier;
import java.util.stream.Stream;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.JavaVersion;
import org.apache.commons.lang3.SystemUtils;
import org.apache.logging.log4j.Logger;
import org.codehaus.cargo.container.ContainerType;
import org.codehaus.cargo.container.InstalledLocalContainer;
import org.codehaus.cargo.container.State;
import org.codehaus.cargo.container.configuration.ConfigurationType;
import org.codehaus.cargo.container.configuration.LocalConfiguration;
import org.codehaus.cargo.container.deployable.WAR;
import org.codehaus.cargo.container.property.GeneralPropertySet;
import org.codehaus.cargo.container.property.LoggingLevel;
import org.codehaus.cargo.container.property.ServletPropertySet;
import org.codehaus.cargo.container.tomcat.TomcatPropertySet;
import org.codehaus.cargo.generic.DefaultContainerFactory;
import org.codehaus.cargo.generic.configuration.DefaultConfigurationFactory;

import org.apache.geode.logging.internal.log4j.api.LogService;

/**
 * Base class for handling the setup and configuration of cargo containers
 *
 * This class contains common logic for setting up and configuring cargo containers for J2EE
 * container installations. Also includes some common methods for applying geode session replication
 * configuration to those containers.
 *
 * Subclasses provide setup and configuration of specific containers.
 */
public abstract class ServerContainer {
  private final File containerConfigHome;
  private final IntSupplier portSupplier;
  private InstalledLocalContainer container;
  private ContainerInstall install;

  private String locatorAddress;
  private int locatorPort;
  private File warFile;

  public String description;
  public File gemfireLogFile;
  public File cacheXMLFile;
  public File cargoLogDir;

  public String loggingLevel;

  public HashMap<String, String> cacheProperties;
  public HashMap<String, String> systemProperties;

  public final String DEFAULT_CONF_DIR;

  public static final String DEFAULT_LOGGING_LEVEL = LoggingLevel.LOW.getLevel();
  public static final String DEFAULT_LOG_DIR = "cargo_logs/";
  public static final String DEFAULT_CONFIG_DIR = TMP_DIR + "/cargo_configs/";

  public static final Logger logger = LogService.getLogger();

  /**
   * Sets up the container using the given installation
   *
   * Sets up a bunch of logging files, default locations, and container properties.
   *
   * Creates a whole new cargo configuration and cargo container for the {@link #container}
   * variable.
   *
   * @param containerConfigHome The folder that the container configuration folder should be setup
   *        in
   * @param containerDescriptors A string of extra descriptors for the container used in the
   *        containers {@link #description}
   * @param portSupplier allocates ports for use by the container
   */
  public ServerContainer(ContainerInstall install, File containerConfigHome,
      String containerDescriptors, IntSupplier portSupplier) throws IOException {
    this.install = install;
    this.portSupplier = portSupplier;
    // Get a container description for logging and output
    description = generateUniqueContainerDescription(containerDescriptors);
    // Setup logging
    loggingLevel = DEFAULT_LOGGING_LEVEL;
    cargoLogDir = new File(DEFAULT_LOG_DIR + description);
    cargoLogDir.mkdirs();

    logger.info("Creating new container {}", description);

    DEFAULT_CONF_DIR = install.getHome() + "/conf/";
    // Use the default configuration home path if not passed a config home
    this.containerConfigHome = containerConfigHome == null
        ? new File(DEFAULT_CONFIG_DIR + description) : containerConfigHome;

    // Init the property lists
    cacheProperties = new HashMap<>();
    systemProperties = new HashMap<>();
    // Set WAR file to session testing war
    warFile = new File(install.getWarFilePath());

    // Create the Cargo Container instance wrapping our physical container
    LocalConfiguration configuration = (LocalConfiguration) new DefaultConfigurationFactory()
        .createConfiguration(install.getInstallId(), ContainerType.INSTALLED,
            ConfigurationType.STANDALONE, this.containerConfigHome.getAbsolutePath());
    // Set configuration/container logging level
    configuration.setProperty(GeneralPropertySet.LOGGING, loggingLevel);
    // Removes secureRandom generation so that container startup is much faster
    configuration.setProperty(GeneralPropertySet.JVMARGS,
        "-Djava.security.egd=file:/dev/./urandom");

    // Setup the gemfire log file for this container
    gemfireLogFile = new File(cargoLogDir.getAbsolutePath() + "/gemfire.log");
    gemfireLogFile.getParentFile().mkdirs();
    setSystemProperty("log-file", gemfireLogFile.getAbsolutePath());

    logger.info("Gemfire logs can be found in {}", gemfireLogFile.getAbsolutePath());

    // Create the container
    container = (InstalledLocalContainer) (new DefaultContainerFactory())
        .createContainer(install.getInstallId(), ContainerType.INSTALLED, configuration);
    // Set container's home dir to where it was installed
    container.setHome(install.getHome());
    // Set container output log to directory setup for it
    container.setOutput(cargoLogDir.getAbsolutePath() + "/container.log");

    // Set cacheXML file
    File installXMLFile = install.getCacheXMLFile();
    // Sets the cacheXMLFile variable and adds the cache XML file server system property map
    setCacheXMLFile(new File(cargoLogDir.getAbsolutePath() + "/" + installXMLFile.getName()));
    // Copy the cacheXML file to a new, unique location for this container
    FileUtils.copyFile(installXMLFile, cacheXMLFile);
  }

  /**
   * Generates a unique, mostly human readable, description string of the container using the
   * installation's description, extraIdentifiers, and the current system nano time
   */
  public String generateUniqueContainerDescription(String extraIdentifiers) {
    return String.join("_", Arrays.asList(install.getInstallDescription(), extraIdentifiers,
        UUID.randomUUID().toString()));
  }

  /**
   * Deploys the {@link #warFile} to the cargo container ({@link #container}).
   */
  public void deployWar() {
    // Get the cargo war from the war file
    WAR war = new WAR(warFile.getAbsolutePath());
    // Set context access to nothing
    war.setContext("");
    // Deploy the war the container's configuration
    getConfiguration().addDeployable(war);

    logger.info("Deployed WAR file at {}", war.getFile());
  }

  /**
   * Starts this cargo container by picking the container's ports (RMI, AJP, and regular) and
   * calling the cargo container's start function
   */
  public void start() {
    if (container.getState().isStarted())
      throw new IllegalArgumentException("Container " + description
          + " failed to start because it is currently " + container.getState());

    LocalConfiguration config = getConfiguration();
    // Set container ports from available ports
    int servletPort = portSupplier.getAsInt();
    int containerRmiPort = portSupplier.getAsInt();
    int tomcatAjpPort = portSupplier.getAsInt();
    config.setProperty(ServletPropertySet.PORT, Integer.toString(servletPort));
    config.setProperty(GeneralPropertySet.RMI_PORT, Integer.toString(containerRmiPort));
    config.setProperty(TomcatPropertySet.AJP_PORT, Integer.toString(tomcatAjpPort));
    config.setProperty(GeneralPropertySet.PORT_OFFSET, "0");
    int jvmJmxPort = portSupplier.getAsInt();
    String jvmArgs = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=" + jvmJmxPort;
    if (SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_9)) {
      jvmArgs += " --add-opens java.base/java.lang.module=ALL-UNNAMED" +
          " --add-opens java.base/jdk.internal.module=ALL-UNNAMED" +
          " --add-opens java.base/jdk.internal.reflect=ALL-UNNAMED" +
          " --add-opens java.base/jdk.internal.misc=ALL-UNNAMED" +
          " --add-opens java.base/jdk.internal.ref=ALL-UNNAMED" +
          " --add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED";
    }
    config.setProperty(GeneralPropertySet.START_JVMARGS, jvmArgs);
    container.setConfiguration(config);


    try {
      logger.info("Starting container {} RMI Port: {}", description, jvmJmxPort);
      // Writes settings to the expected form (either XML or WAR file)
      writeSettings();
      // Start the container through cargo
      container.start();
    } catch (Exception e) {
      throw new RuntimeException(
          "Something very bad happened to this container when starting. Check the cargo_logs folder for container logs.",
          e);
    }
  }

  /**
   * Stops this cargo container
   */
  public void stop() {
    if (!container.getState().isStarted()) {
      throw new IllegalArgumentException("Container " + description
          + " failed to stop because it is currently " + container.getState());
    }

    container.stop();
  }

  public void dumpLogs() {
    System.out.println("Logs for container " + this);
    dumpLogsInDir(cargoLogDir.toPath());
    dumpLogsInDir(containerConfigHome.toPath().resolve("logs"));
    dumpConfiguration();
  }

  private static void dumpLogsInDir(Path dir) {
    try (Stream<Path> paths = Files.list(dir)) {
      paths.forEach(ServerContainer::dumpToStdOut);
    } catch (IOException thrown) {
      System.out.println("-------------------------------------------");
      System.out.println("Exception while dumping log files from directory to stdout.");
      System.out.println("   Directory: " + dir.toAbsolutePath());
      System.out.println("   Exception: " + thrown);
      System.out.println("-------------------------------------------");
    }
  }

  private static void dumpToStdOut(Path path) {
    System.out.println("-------------------------------------------");
    System.out.println(path.toAbsolutePath());
    System.out.println("-------------------------------------------");
    try {
      Files.copy(path, System.out);
    } catch (IOException thrown) {
      System.out.println("Exception while dumping log file to stdout.");
      System.out.println("   File: " + path.toAbsolutePath());
      System.out.println("   Exception: " + thrown);
    }
    System.out.println("-------------------------------------------");
    System.out.println();
  }

  private void dumpConfiguration() {
    System.out.println("-------------------------------------------");
    System.out.println("Configuration for container " + this);
    System.out.println("-------------------------------------------");
    LocalConfiguration configuration = getConfiguration();
    System.out.format("Name: %s%n", configuration);
    System.out.format("Class: %s%n", configuration.getClass());
    System.out.println("Properties:");
    configuration.getProperties().entrySet().forEach(System.out::println);
    System.out.println("-------------------------------------------");
    System.out.println();
  }

  /**
   * Copies the container configuration (found through {@link #getConfiguration()}) to the logging
   * directory specified by {@link #cargoLogDir}
   */
  public void cleanUp() throws IOException {
    File configDir = new File(getConfiguration().getHome());

    if (configDir.exists()) {
      logger.info("Deleting configuration folder {}", configDir.getAbsolutePath());
      FileUtils.deleteDirectory(configDir);
    }
  }

  /**
   * Sets the container's locator
   *
   * Sets the two variables {@link #locatorAddress} and {@link #locatorPort}. Also calls the
   * {@link #updateLocator()} function to write the updated locator properties to the file.
   */
  public void setLocator(String address, int port) throws IOException {
    locatorAddress = address;
    locatorPort = port;
    updateLocator();
  }

  /**
   * Sets the container's cache XML file
   */
  public void setCacheXMLFile(File cacheXMLFile) throws IOException {
    setSystemProperty("cache-xml-file", cacheXMLFile.getAbsolutePath());
    this.cacheXMLFile = cacheXMLFile;
  }

  /**
   * Set a geode session replication property
   */
  public String setCacheProperty(String name, String value) throws IOException {
    return cacheProperties.put(name, value);
  }

  /**
   * Set geode distributed system property
   */
  public String setSystemProperty(String name, String value) throws IOException {
    return systemProperties.put(name, value);
  }

  /**
   * Sets the war file for this container to deploy and use
   */
  public void setWarFile(File warFile) {
    this.warFile = warFile;
  }

  /**
   * set the container's logging level
   */
  public void setLoggingLevel(String loggingLevel) {
    this.loggingLevel = loggingLevel;

    LocalConfiguration config = getConfiguration();
    config.setProperty(GeneralPropertySet.LOGGING, loggingLevel);
    container.setConfiguration(config);
  }

  public InstalledLocalContainer getContainer() {
    return container;
  }

  public ContainerInstall getInstall() {
    return install;
  }

  public File getWarFile() {
    return warFile;
  }

  public String getLoggingLevel() {
    return loggingLevel;
  }

  public LocalConfiguration getConfiguration() {
    return container.getConfiguration();
  }

  public State getState() {
    return container.getState();
  }

  public String getCacheProperty(String name) {
    return cacheProperties.get(name);
  }

  public String getSystemProperty(String name) {
    return systemProperties.get(name);
  }

  /**
   * Get the RMI port for the container
   *
   * Calls {@link #getPort()} with the {@link GeneralPropertySet#RMI_PORT} option.
   */
  public String getRMIPort() {
    return getPort(GeneralPropertySet.RMI_PORT);
  }

  /**
   * Get the basic port for the container
   *
   * Calls {@link #getPort()} with the {@link ServletPropertySet#PORT} option.
   */
  public String getPort() {
    return getPort(ServletPropertySet.PORT);
  }

  /**
   * The container's port for the specified port type
   */
  public String getPort(String portType) {
    LocalConfiguration config = getConfiguration();
    config.applyPortOffset();

    if (!container.getState().isStarted())
      throw new IllegalStateException(
          "Container is not started, thus a port has not yet been assigned to the container.");

    return config.getPropertyValue(portType);
  }

  /**
   * Called before each container startup
   *
   * This is mainly used to write properties to whatever format they need to be in for a given
   * container before the container is started. The reason for doing this is to make sure that
   * expensive property updates (such as writing to an XML file or building WAR files from the
   * command line) only happen as often as they are needed. These kinds of updates usually only need
   * to happen on container startup.
   */
  public abstract void writeSettings() throws Exception;

  /**
   * Human readable description of the container
   *
   * @return The {@link #description} variable along with the state of this {@link #container}
   */
  @Override
  public String toString() {
    return description + "_<" + container.getState() + ">";
  }

  /**
   * Updates the address and port of the locator for this container
   *
   * For Client Server installations the {@link #cacheXMLFile} is updated with the new address and
   * port. For Peer to Peer installations the locator must be specified as a system property and so
   * is added to the {@link #systemProperties} map under the 'locators' key in the form of
   * '{@link #locatorAddress}[{@link #locatorPort}]'.
   */
  private void updateLocator() throws IOException {
    if (getInstall().isClientServer()) {
      HashMap<String, String> attributes = new HashMap<>();
      attributes.put("host", locatorAddress);
      attributes.put("port", Integer.toString(locatorPort));

      ContainerInstall.editXMLFile(cacheXMLFile.getAbsolutePath(), "locator", "pool",
          attributes, true);
    } else {
      setSystemProperty("locators", locatorAddress + "[" + locatorPort + "]");
    }
  }
}
