/*
 * 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 java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.function.IntSupplier;

/**
 * Container install for a generic app server
 *
 * Extends {@link ContainerInstall} to form a basic installer which downloads and sets up an
 * installation to build a container off of. Currently being used solely for Jetty 12 installation.
 *
 * This install is used to setup many different generic app server containers using
 * {@link GenericAppServerContainer}.
 *
 * In theory, adding support for additional appserver installations should just be a matter of
 * adding new elements to the {@link GenericAppServerVersion} enumeration, since this install does
 * not do much modification of the installation itself. There is very little (maybe no) Jetty 12
 * specific code outside of the {@link GenericAppServerVersion}.
 */
public class GenericAppServerInstall extends ContainerInstall {
  private static final String JETTY_VERSION = "12.0.27";

  /**
   * Get the version number, download URL, and container name of a generic app server using
   * hardcoded keywords
   *
   * Currently supports JETTY12 for Jakarta EE 10 compatibility.
   */
  public enum GenericAppServerVersion {
    JETTY12(12, "jetty-home-" + JETTY_VERSION + ".zip", "jetty");

    private final int version;
    private final String downloadURL;
    private final String containerName;

    GenericAppServerVersion(int version, String downloadURL, String containerName) {
      this.version = version;
      this.downloadURL = downloadURL;
      this.containerName = containerName;
    }

    public int getVersion() {
      return version;
    }

    public String getDownloadURL() {
      return downloadURL;
    }

    public String getContainerId() {
      return containerName + getVersion() + "x";
    }
  }

  private final GenericAppServerVersion version;

  public GenericAppServerInstall(String name, GenericAppServerVersion version,
      ConnectionType connType, IntSupplier portSupplier) throws IOException {
    this(Files.createTempDirectory("geode_container_install").toAbsolutePath(), name, version,
        connType, portSupplier);
  }

  public GenericAppServerInstall(Path rootDir, String name, GenericAppServerVersion version,
      ConnectionType connType, IntSupplier portSupplier) throws IOException {
    super(rootDir, name, version.getDownloadURL(), connType, "appserver", portSupplier);

    this.version = version;
  }

  /**
   * Implementation of {@link ContainerInstall#generateContainer(Path, Path, String)}, which
   * generates a
   * generic appserver specific container
   *
   * Creates a {@link GenericAppServerContainer} instance off of this installation.
   *
   * @param containerDescriptors Additional descriptors used to identify a container
   */
  @Override
  public GenericAppServerContainer generateContainer(Path rootDir,
      Path containerConfigHome,
      String containerDescriptors) throws IOException {
    return new GenericAppServerContainer(this, rootDir, containerConfigHome, containerDescriptors,
        portSupplier());
  }

  /**
   * The cargo specific installation id needed to setup a cargo container
   *
   * Based on the installation's {@link #version}.
   */
  @Override
  public String getInstallId() {
    return version.getContainerId();
  }

  /**
   * @see ContainerInstall#getInstallDescription()
   */
  @Override
  public String getInstallDescription() {
    return version.name() + "_" + getConnectionType().getName();
  }

  /**
   * Get the GenericAppServerVersion for this installation
   *
   * @return the version of the generic app server
   */
  public GenericAppServerVersion getGenericAppServerVersion() {
    return version;
  }

  /**
   * Implements {@link ContainerInstall#getContextSessionManagerClass()}
   *
   * @throws IllegalArgumentException Always throws an illegal argument exception because app
   *         servers should not need the session manager class
   */
  @Override
  public String getContextSessionManagerClass() {
    throw new IllegalArgumentException(
        "Bad method call. Generic app servers do not use TomcatDeltaSessionManagers.");
  }
}
