/*
 * The Alluxio Open Foundation licenses this work under the Apache License, version 2.0
 * (the "License"). You may not use this work except in compliance with the License, which is
 * available at www.apache.org/licenses/LICENSE-2.0
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied, as more fully set forth in the License.
 *
 * See the NOTICE file distributed with this work for information regarding copyright ownership.
 */

package alluxio;

import alluxio.conf.ServerConfiguration;
import alluxio.conf.PropertyKey;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Utility methods for Alluxio {@link Process}es.
 */
public final class ProcessUtils {
  private static final Logger LOG = LoggerFactory.getLogger(ProcessUtils.class);

  /**
   * Runs the given {@link Process}. This method should only be called from {@code main()} methods.
   *
   * @param process the {@link Process} to run
'   */
  public static void run(Process process) {
    try {
      LOG.info("Starting {}.", process);
      process.start();
      LOG.info("Stopping {}.", process);
      System.exit(0);
    } catch (Throwable t) {
      LOG.error("Uncaught exception while running {}, stopping it and exiting. "
              + "Exception {}, Root Cause {}", process, t, ExceptionUtils.getRootCause(t));
      try {
        process.stop();
      } catch (Throwable t2) {
        // continue to exit
        LOG.error("Uncaught exception while stopping {}, simply exiting. "
                + "Exception {}, Root Cause {}",
            process, t2, ExceptionUtils.getRootCause(t2));
      }
      System.exit(-1);
    }
  }

  /**
   * Logs a fatal error and then exits the system.
   *
   * @param logger the logger to log to
   * @param format the error message format string
   * @param args args for the format string
   */
  public static void fatalError(Logger logger, String format, Object... args) {
    fatalError(logger, null, format, args);
  }

  /**
   * Logs a fatal error and then exits the system.
   *
   * @param logger the logger to log to
   * @param t the throwable causing the fatal error
   * @param format the error message format string
   * @param args args for the format string
   */
  public static void fatalError(Logger logger, Throwable t, String format, Object... args) {
    String message = String.format("Fatal error: " + format, args);
    if (t != null) {
      message += "\n" + ExceptionUtils.getStackTrace(t);
    }
    if (ServerConfiguration.getBoolean(PropertyKey.TEST_MODE)) {
      throw new RuntimeException(message);
    }
    logger.error(message);
    System.exit(-1);
  }

  /**
   * Adds a shutdown hook that will be invoked when a signal is sent to this process.
   *
   * The process may be utilizing some resources, and this shutdown hook will be invoked by
   * JVM when a SIGTERM is sent to the process by "kill" command. The shutdown hook calls
   * {@link Process#stop()} method to cleanly release the resources and exit.
   *
   * @param process the data structure representing the process to terminate
   */
  public static void stopProcessOnShutdown(final Process process) {
    Runtime.getRuntime().addShutdownHook(new Thread(() -> {
      try {
        process.stop();
      } catch (Throwable t) {
        LOG.error("Failed to stop process", t);
      }
    }, "alluxio-process-shutdown-hook"));
  }

  private ProcessUtils() {} // prevent instantiation
}

@@ -545,35 +545,27 @@
 io.conf.
-ServerConfiguration
+PropertyKey
 ;%0Aimport
@@ -578,27 +578,35 @@
 io.conf.
-PropertyKey
+ServerConfiguration
 ;%0A%0Aimpor
@@ -1052,15 +1052,14 @@
 run%0A
-'
    */%0A
+
   pu
@@ -1346,36 +1346,32 @@
 ng. %22%0A          
-    
 + %22Exception %7B%7D,
@@ -1359,34 +1359,38 @@
    + %22Exception 
-%7B%7D
+%5C%22%7B%7D%5C%22
 , Root Cause %7B%7D%22
@@ -1386,18 +1386,22 @@
 t Cause 
-%7B%7D
+%5C%22%7B%7D%5C%22
 %22, proce
@@ -1437,16 +1437,19 @@
 Cause(t)
+, t
 );%0A     
@@ -1621,28 +1621,24 @@
             
-    
 + %22Exception
@@ -1638,18 +1638,22 @@
 ception 
-%7B%7D
+%5C%22%7B%7D%5C%22
 , Root C
@@ -1661,24 +1661,16 @@
 use 
-%7B%7D%22,%0A           
+%5C%22%7B%7D%5C%22%22,
  pro
@@ -1710,16 +1710,32 @@
 ause(t2)
+,%0A            t2
 );%0A     

Fix a regression in priting StackTrace on exception