/*
 * 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.perftest.jvms;

import static org.apache.geode.distributed.ConfigurationProperties.SSL_KEYSTORE;
import static org.apache.geode.distributed.ConfigurationProperties.SSL_KEYSTORE_PASSWORD;
import static org.apache.geode.distributed.ConfigurationProperties.SSL_TRUSTSTORE;
import static org.apache.geode.distributed.ConfigurationProperties.SSL_TRUSTSTORE_PASSWORD;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.geode.perftest.infrastructure.Infrastructure;
import org.apache.geode.perftest.jvms.rmi.ChildJVM;

class JVMLauncher {
  private static final Logger logger = LoggerFactory.getLogger(RemoteJVMFactory.class);
  public static final String WITH_STRACE = "benchmark.withStrace";

  JVMLauncher() {}

  CompletableFuture<Void> launchProcesses(Infrastructure infra, int rmiPort,
      List<JVMMapping> mapping)
      throws UnknownHostException {
    List<CompletableFuture<Void>> futures = new ArrayList<CompletableFuture<Void>>();
    for (JVMMapping entry : mapping) {
      CompletableFuture<Void> future = launchWorker(infra, rmiPort, entry);
      futures.add(future);
    }
    return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
  }

  CompletableFuture<Void> launchWorker(Infrastructure infra, int rmiPort,
      JVMMapping jvmConfig)
      throws UnknownHostException {
    final String[] shellCommand = traceCommand(
        buildCommand(InetAddress.getLocalHost().getHostAddress(), rmiPort, jvmConfig), jvmConfig);

    CompletableFuture<Void> future = new CompletableFuture<>();
    Thread thread = new Thread("Worker " + jvmConfig.getNode().getAddress()) {
      public void run() {

        try {
          infra.onNode(jvmConfig.getNode(), new String[] {"rm", "-rf", jvmConfig.getOutputDir()});
          infra.onNode(jvmConfig.getNode(), new String[] {"mkdir", "-p", jvmConfig.getOutputDir()});
          int result = infra.onNode(jvmConfig.getNode(), shellCommand);
          if (result != 0) {
            logger.error("ChildJVM exited with error code " + result);
          }
        } catch (Throwable t) {
          logger.error("Launching " + String.join(" ", shellCommand) + " on " + jvmConfig.getNode()
              + "Failed.", t);
        } finally {
          future.complete(null);
        }
      }
    };
    thread.start();

    return future;
  }

  String[] traceCommand(final String[] command, JVMMapping jvmConfig) {
    List<String> strace = new ArrayList<>();

    if (Boolean.getBoolean(WITH_STRACE)) {
      strace.add("strace");
      strace.add("-o");
      strace.add(jvmConfig.getOutputDir() + "/java.strace");
      strace.add("-ttt");
      strace.add("-T");
      strace.add("-f");
      strace.add("-ff");
    }

    strace.addAll(Arrays.asList(command));

    return strace.toArray(new String[0]);
  }

  String[] buildCommand(String rmiHost, int rmiPort, JVMMapping jvmConfig) {

    List<String> command = new ArrayList<>();
    command.add(System.getProperty("java.home") + "/bin/java");
    command.add("-classpath");
    command.add(jvmConfig.getLibDir() + "/*");
    command.add("-Djava.library.path=" + System.getProperty("user.home") + "/META-INF/native");
    command.add("-D" + RemoteJVMFactory.RMI_HOST + "=" + rmiHost);
    command.add("-D" + RemoteJVMFactory.RMI_PORT_PROPERTY + "=" + rmiPort);
    command.add("-D" + RemoteJVMFactory.JVM_ID + "=" + jvmConfig.getId());
    command.add("-D" + RemoteJVMFactory.ROLE + "=" + jvmConfig.getRole());
    command.add("-D" + RemoteJVMFactory.OUTPUT_DIR + "=" + jvmConfig.getOutputDir());

    if (jvmConfig.getJvmArgs().contains("-Dbenchmark.withSsl=true")) {
      command
          .add("-Dgemfire." + SSL_KEYSTORE + "=" + jvmConfig.getLibDir() + "/temp-self-signed.jks");
      command.add("-Dgemfire." + SSL_KEYSTORE_PASSWORD + "=123456");
      command.add(
          "-Dgemfire." + SSL_TRUSTSTORE + "=" + jvmConfig.getLibDir() + "/temp-self-signed.jks");
      command.add("-Dgemfire." + SSL_TRUSTSTORE_PASSWORD + "=123456");
    }
    command.addAll(replaceTokens(jvmConfig.getJvmArgs(), jvmConfig));
    command.add(ChildJVM.class.getName());

    return command.toArray(new String[0]);
  }

  private static final List<String> replaceTokens(List<String> args, JVMMapping jvmConfig) {
    List<String> replaced = new ArrayList<>(args.size());
    for (String arg : args) {
      replaced.add(replaceTokens(arg, jvmConfig));
    }
    return replaced;
  }

  private static String replaceTokens(String arg, JVMMapping jvmConfig) {
    arg = arg.replace("OUTPUT_DIR", jvmConfig.getOutputDir());
    arg = arg.replace("JVM_ROLE", jvmConfig.getRole());
    arg = arg.replace("JVM_ID", Integer.toString(jvmConfig.getId()));
    return arg;
  }
}
