/*
 * 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.CACHE_XML_NOT_FOUND_MESSAGE;
import static org.apache.geode.management.internal.cli.i18n.CliStrings.CREATE_REGION;
import static org.apache.geode.management.internal.cli.i18n.CliStrings.CREATE_REGION__REGION;
import static org.apache.geode.management.internal.cli.i18n.CliStrings.CREATE_REGION__REGIONSHORTCUT;
import static org.apache.geode.management.internal.cli.i18n.CliStrings.GEODE_0_PROPERTIES_1_NOT_FOUND_MESSAGE;
import static org.apache.geode.management.internal.cli.i18n.CliStrings.GROUP;
import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER;
import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__CACHE_XML_FILE;
import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__DIR;
import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__FORCE;
import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__HOSTNAME__FOR__CLIENTS;
import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__LOCATORS;
import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__MAXHEAP;
import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__NAME;
import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__OFF_HEAP_MEMORY_SIZE;
import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__PROPERTIES;
import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__SECURITY_PROPERTIES;
import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__SERVER_PORT;
import static org.apache.geode.management.internal.cli.i18n.CliStrings.START_SERVER__USERNAME;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.isA;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Serializable;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.file.Paths;
import java.util.List;

import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;

import org.apache.geode.cache.client.internal.locator.GetAllServersRequest;
import org.apache.geode.cache.client.internal.locator.GetAllServersResponse;
import org.apache.geode.cache.execute.FunctionException;
import org.apache.geode.cache.execute.FunctionService;
import org.apache.geode.distributed.AbstractLauncher;
import org.apache.geode.distributed.ServerLauncher;
import org.apache.geode.distributed.internal.InternalLocator;
import org.apache.geode.distributed.internal.ServerLocation;
import org.apache.geode.distributed.internal.ServerLocator;
import org.apache.geode.internal.AvailablePortHelper;
import org.apache.geode.internal.process.ProcessType;
import org.apache.geode.internal.process.ProcessUtils;
import org.apache.geode.management.internal.cli.i18n.CliStrings;
import org.apache.geode.management.internal.cli.util.CommandStringBuilder;
import org.apache.geode.test.compiler.ClassBuilder;
import org.apache.geode.test.dunit.rules.ClusterStartupRule;
import org.apache.geode.test.dunit.rules.MemberVM;
import org.apache.geode.test.dunit.rules.SharedErrorCollector;
import org.apache.geode.test.junit.rules.GfshCommandRule;
import org.apache.geode.test.junit.rules.RequiresGeodeHome;
import org.apache.geode.test.junit.rules.serializable.SerializableTemporaryFolder;
import org.apache.geode.test.junit.rules.serializable.SerializableTestName;

public class StartServerCommandDUnitTest implements Serializable {

  private static MemberVM locator;
  private static String locatorConnectionString;

  private File workingDir;
  private String memberName;
  private int serverPort;

  @ClassRule
  public static RequiresGeodeHome requiresGeodeHome = new RequiresGeodeHome();

  @ClassRule
  public static ClusterStartupRule cluster = new ClusterStartupRule();

  @ClassRule
  public static GfshCommandRule gfsh = new GfshCommandRule();

  @Rule
  public SharedErrorCollector errorCollector = new SharedErrorCollector();

  @Rule
  public SerializableTemporaryFolder temporaryFolder = new SerializableTemporaryFolder();

  @Rule
  public SerializableTestName testName = new SerializableTestName();

  @BeforeClass
  public static void beforeClass() throws Exception {
    // locator used to clean up members started during tests
    locator = cluster.startLocatorVM(0, 0);

    locatorConnectionString = "localhost[" + locator.getPort() + "]";

    gfsh.connectAndVerify(locator);
  }

  @Before
  public void before() throws IOException {
    workingDir = temporaryFolder.newFolder();
    memberName = testName.getMethodName();
    serverPort = AvailablePortHelper.getRandomAvailableTCPPort();
  }

  @AfterClass
  public static void afterClass() throws Exception {
    gfsh.connectAndVerify(locator);
    gfsh.execute("shutdown --include-locators");
  }

  @Test
  public void testWithMissingCacheXml() throws IOException {
    String missingCacheXmlPath =
        Paths.get("missing", "cache.xml").toAbsolutePath().toString();
    String expectedError =
        CliStrings.format(CACHE_XML_NOT_FOUND_MESSAGE, missingCacheXmlPath);

    String command = new CommandStringBuilder(START_SERVER)
        .addOption(START_SERVER__NAME, memberName)
        .addOption(START_SERVER__LOCATORS, locatorConnectionString)
        .addOption(START_SERVER__SERVER_PORT, String.valueOf(serverPort))
        .addOption(START_SERVER__CACHE_XML_FILE, missingCacheXmlPath)
        .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
        .getCommandString();

    gfsh.executeAndAssertThat(command).statusIsError()
        .containsOutput(expectedError);
  }

  @Test
  public void testWithMissingGemFirePropertiesFile() throws IOException {
    String missingGemfirePropertiesPath =
        Paths.get("missing", "gemfire.properties").toAbsolutePath().toString();
    String expectedError =
        CliStrings.format(GEODE_0_PROPERTIES_1_NOT_FOUND_MESSAGE, "", missingGemfirePropertiesPath);

    String command = new CommandStringBuilder(START_SERVER)
        .addOption(START_SERVER__NAME, memberName)
        .addOption(START_SERVER__LOCATORS, locatorConnectionString)
        .addOption(START_SERVER__SERVER_PORT, String.valueOf(serverPort))
        .addOption(START_SERVER__PROPERTIES, missingGemfirePropertiesPath)
        .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
        .getCommandString();

    gfsh.executeAndAssertThat(command).statusIsError()
        .containsOutput(expectedError);
  }

  @Test
  public void testWithMissingPassword() throws IOException {
    String expectedError = "password must be specified.";

    String command = new CommandStringBuilder(START_SERVER)
        .addOption(START_SERVER__NAME, memberName)
        .addOption(START_SERVER__LOCATORS, locatorConnectionString)
        .addOption(START_SERVER__SERVER_PORT, String.valueOf(serverPort))
        .addOption(START_SERVER__USERNAME, "usernameValue")
        .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
        .getCommandString();

    gfsh.executeAndAssertThat(command).statusIsError()
        .containsOutput(expectedError);
  }

  @Test
  public void testWithMissingSecurityPropertiesFile() throws IOException {
    String missingSecurityPropertiesPath =
        Paths.get("missing", "security.properties").toAbsolutePath().toString();
    String expectedError = CliStrings.format(GEODE_0_PROPERTIES_1_NOT_FOUND_MESSAGE,
        "Security ", missingSecurityPropertiesPath);

    String command = new CommandStringBuilder(START_SERVER)
        .addOption(START_SERVER__NAME, memberName)
        .addOption(START_SERVER__LOCATORS, locatorConnectionString)
        .addOption(START_SERVER__SERVER_PORT, String.valueOf(serverPort))
        .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
        .addOption(START_SERVER__SECURITY_PROPERTIES, missingSecurityPropertiesPath)
        .getCommandString();

    gfsh.executeAndAssertThat(command).statusIsError()
        .containsOutput(expectedError);
  }

  @Test
  public void testWithUnavailablePort() throws IOException {
    String expectedError =
        "java.lang.RuntimeException: An IO error occurred while starting a Server";
    String expectedCause = "Caused by: java.net.BindException: "
        + "Network is unreachable; port (" + serverPort + ") is not available on localhost.";

    try (Socket interferingProcess = new Socket()) {
      // make the target port unavailable
      interferingProcess.bind(new InetSocketAddress(serverPort));

      String command = new CommandStringBuilder(START_SERVER)
          .addOption(START_SERVER__NAME, memberName)
          .addOption(START_SERVER__LOCATORS, locatorConnectionString)
          .addOption(START_SERVER__SERVER_PORT, String.valueOf(serverPort))
          .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
          .getCommandString();

      gfsh.executeAndAssertThat(command).statusIsError()
          .hasOutput().contains(expectedError, expectedCause);
    }
  }

  @Test
  public void testWithAvailablePort() throws IOException {
    String expectedMessage = "Server in " + workingDir.getCanonicalPath();
    String expectedMessage2 = "as " + memberName + " is currently online.";

    String command = new CommandStringBuilder(START_SERVER)
        .addOption(START_SERVER__NAME, memberName)
        .addOption(START_SERVER__LOCATORS, locatorConnectionString)
        .addOption(START_SERVER__SERVER_PORT, String.valueOf(serverPort))
        .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
        .getCommandString();

    gfsh.executeAndAssertThat(command).statusIsSuccess()
        .hasOutput().contains(expectedMessage, expectedMessage2);
  }

  @Test
  public void testWithConflictingPIDFile() throws Exception {
    String fileName = ProcessType.SERVER.getPidFileName();

    // create PID file
    File pidFile = new File(workingDir.getAbsolutePath(), fileName);
    assertThat(pidFile.createNewFile()).isTrue();

    // write PID to PID file
    try (FileWriter fileWriter = new FileWriter(pidFile, false)) {
      fileWriter.write(ProcessUtils.identifyPid() + "\n");
      fileWriter.flush();
    }
    assertThat(pidFile.isFile()).isTrue();

    String command = new CommandStringBuilder(START_SERVER)
        .addOption(START_SERVER__NAME, memberName)
        .addOption(START_SERVER__LOCATORS, locatorConnectionString)
        .addOption(START_SERVER__SERVER_PORT, String.valueOf(serverPort))
        .addOption(START_SERVER__DIR, pidFile.getParentFile().getCanonicalPath())
        .getCommandString();

    String expectedError = "A PID file already exists and a Server may be running in "
        + pidFile.getParentFile().getCanonicalPath();
    String expectedCause = "Caused by: "
        + "org.apache.geode.internal.process.FileAlreadyExistsException: Pid file already exists: "
        + pidFile.getCanonicalPath();

    gfsh.executeAndAssertThat(command).statusIsError()
        .hasOutput().contains(expectedError, expectedCause);
  }

  @Test
  public void testWithForceOverwriteConflictingPIDFile() throws Exception {
    String fileName = ProcessType.SERVER.getPidFileName();

    // create PID file
    File pidFile = new File(workingDir.getAbsolutePath(), fileName);
    assertThat(pidFile.createNewFile()).isTrue();

    // write PID to PID file
    try (FileWriter fileWriter = new FileWriter(pidFile, false)) {
      fileWriter.write(ProcessUtils.identifyPid() + "\n");
      fileWriter.flush();
    }
    assertThat(pidFile.isFile()).isTrue();

    String command = new CommandStringBuilder(START_SERVER)
        .addOption(START_SERVER__NAME, memberName)
        .addOption(START_SERVER__LOCATORS, locatorConnectionString)
        .addOption(START_SERVER__SERVER_PORT, String.valueOf(serverPort))
        .addOption(START_SERVER__DIR, pidFile.getParentFile().getCanonicalPath())
        .addOption(START_SERVER__FORCE, "true")
        .getCommandString();

    String expectedMessage = "Server in " + pidFile.getParentFile().getCanonicalPath();

    gfsh.executeAndAssertThat(command).statusIsSuccess()
        .containsOutput(expectedMessage);
  }

  @Test
  public void testWithConnectionToLocator() throws IOException {
    String expectedVersionPattern = "Geode Version: \\d+\\.\\d+\\.\\d+";
    String expectedMessage = "Server in " + workingDir.getCanonicalPath();

    String command = new CommandStringBuilder(START_SERVER)
        .addOption(START_SERVER__NAME, memberName)
        .addOption(START_SERVER__LOCATORS, locatorConnectionString)
        .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
        .addOption(START_SERVER__SERVER_PORT, String.valueOf(serverPort))
        .getCommandString();

    gfsh.executeAndAssertThat(command).statusIsSuccess()
        .hasOutput()
        .contains(expectedMessage)
        .doesNotContainPattern("Gem[Ff]ire Version")
        .containsPattern(expectedVersionPattern);
  }

  @Test
  public void testServerJVMTerminatesOnOutOfMemoryError() throws IOException {
    String groupName = "serverGroup";
    String regionName = "testRegion";

    MemberVM server = cluster.startServerVM(1, locator.getPort());

    String command = new CommandStringBuilder(START_SERVER)
        .addOption(START_SERVER__NAME, memberName)
        .addOption("group", groupName)
        .addOption(START_SERVER__LOCATORS, locatorConnectionString)
        .addOption(START_SERVER__OFF_HEAP_MEMORY_SIZE, "0M")
        .addOption(START_SERVER__MAXHEAP, "300M")
        .addOption(START_SERVER__SERVER_PORT, String.valueOf(serverPort))
        .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
        .getCommandString();

    gfsh.executeAndAssertThat(command).statusIsSuccess();

    command = new CommandStringBuilder(CREATE_REGION)
        .addOption(CREATE_REGION__REGIONSHORTCUT, "PARTITION")
        .addOption(GROUP, groupName)
        .addOption(CREATE_REGION__REGION, regionName)
        .getCommandString();

    gfsh.executeAndAssertThat(command).statusIsSuccess();

    ServerLauncher serverLauncher = new ServerLauncher.Builder()
        .setCommand(ServerLauncher.Command.STATUS)
        .setWorkingDirectory(workingDir.getCanonicalPath())
        .build();
    assertThat(serverLauncher).isNotNull();

    ServerLauncher.ServerState serverState = serverLauncher.status();
    assertThat(serverState.getStatus()).isEqualTo(AbstractLauncher.Status.ONLINE);
    assertThat(serverState.isVmWithProcessIdRunning()).isTrue();

    Integer serverPid = serverState.getPid();
    assertThat(ProcessUtils.isProcessAlive(serverPid)).isTrue();

    String jarName = "RunOutOfMemory.jar";
    File jar = temporaryFolder.newFile(jarName);
    new ClassBuilder().writeJarFromClass(RunOutOfMemoryFunction.class, jar);
    gfsh.executeAndAssertThat("deploy --groups=" + groupName + " --jar=" + jar).statusIsSuccess();

    locator.invoke((() -> {
      try {
        FunctionService.onMember(groupName).execute(new RunOutOfMemoryFunction()).getResult();
      } catch (FunctionException e) {
        errorCollector.checkThat(e, isA(FunctionException.class));
      }
    }));

    gfsh.executeAndAssertThat("list members").statusIsSuccess().doesNotContainOutput(memberName)
        .containsOutput(server.getName());

    server.stop(Boolean.TRUE);

    assertThat(ProcessUtils.isProcessAlive(serverPid)).isFalse();
  }


  @Test
  public void startServerRespectsHostnameForClients() throws IOException {
    String expectedMessagePattern = "Server (.*) is currently online";

    String command = new CommandStringBuilder(START_SERVER)
        .addOption(START_SERVER__NAME, memberName)
        .addOption(START_SERVER__LOCATORS, locatorConnectionString)
        .addOption(START_SERVER__DIR, workingDir.getCanonicalPath())
        .addOption(START_SERVER__SERVER_PORT, String.valueOf(serverPort))
        .addOption(START_SERVER__HOSTNAME__FOR__CLIENTS, "fakeServerName")
        .getCommandString();

    gfsh.executeAndAssertThat(command).statusIsSuccess()
        .hasOutput().containsPattern(expectedMessagePattern);

    // Verify that the ServerLocation contains the specified hostname-for-clients.
    locator.invoke(() -> {
      InternalLocator internalLocator = InternalLocator.getLocator();
      final ServerLocator serverLocator = internalLocator.getServerLocatorAdvisee();
      GetAllServersResponse serversResponse =
          (GetAllServersResponse) serverLocator.processRequest(new GetAllServersRequest());
      List<ServerLocation> locators = serversResponse.getServers();

      assertThat(locators.stream().filter(
          serverLocation -> "fakeServerName".equals(serverLocation.getHostName())))
              .isNotEmpty().hasSize(1);
    });
  }
}
