/*
 * 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.test.dunit;

import static org.apache.geode.test.dunit.Jitter.jitterInterval;
import static org.junit.Assert.fail;

import org.apache.logging.log4j.Logger;

import org.apache.geode.internal.OSProcess;
import org.apache.geode.internal.logging.LogService;

/**
 * <code>ThreadUtils</code> provides static utility methods to perform thread related actions such
 * as dumping thread stacks.
 *
 * These methods can be used directly: <code>ThreadUtils.dumpAllStacks()</code>, however, they are
 * intended to be referenced through static import:
 *
 * <pre>
 * import static org.apache.geode.test.dunit.ThreadUtils.*;
 *    ...
 *    dumpAllStacks();
 * </pre>
 *
 * Extracted from DistributedTestCase.
 */
public class ThreadUtils {

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

  protected ThreadUtils() {}

  /**
   * Print stack dumps for all vms.
   *
   * @since GemFire 5.0
   */
  public static void dumpAllStacks() {
    for (int h = 0; h < Host.getHostCount(); h++) {
      dumpStack(Host.getHost(h));
    }
  }

  /**
   * Dump all thread stacks
   */
  public static void dumpMyThreads() {
    OSProcess.printStacks(0, false);
  }

  /**
   * Print a stack dump for this vm.
   *
   * @since GemFire 5.0
   */
  public static void dumpStack() {
    OSProcess.printStacks(0, false);
  }

  /**
   * Print stack dumps for all vms on the given host.
   *
   * @since GemFire 5.0
   */
  public static void dumpStack(final Host host) {
    for (int v = 0; v < host.getVMCount(); v++) {
      host.getVM(v).invoke(org.apache.geode.test.dunit.ThreadUtils.class, "dumpStack");
    }
  }

  /**
   * Print a stack dump for the given vm.
   *
   * @since GemFire 5.0
   */
  public static void dumpStack(final VM vm) {
    vm.invoke(org.apache.geode.test.dunit.ThreadUtils.class, "dumpStack");
  }

  public static void dumpStackTrace(final Thread thread, final StackTraceElement[] stackTrace) {
    StringBuilder msg = new StringBuilder();
    msg.append("Thread=<").append(thread).append("> stackDump:\n");
    for (int i = 0; i < stackTrace.length; i++) {
      msg.append("\t").append(stackTrace[i]).append("\n");
    }
    logger.info(msg.toString());
  }

  /**
   * Wait for a thread to join.
   *
   * @param async async invocation to wait on
   * @param timeoutMilliseconds maximum time to wait
   * @throws AssertionError if the thread does not terminate
   */
  public static void join(final AsyncInvocation<?> async, final long timeoutMilliseconds) {
    join(async.getThread(), timeoutMilliseconds);
  }

  /**
   * Wait for a thread to join.
   *
   * @param thread thread to wait on
   * @param timeoutMilliseconds maximum time to wait
   * @throws AssertionError if the thread does not terminate
   */
  public static void join(final Thread thread, final long timeoutMilliseconds) {
    final long tilt = System.currentTimeMillis() + timeoutMilliseconds;
    final long incrementalWait = jitterInterval(timeoutMilliseconds);
    final long start = System.currentTimeMillis();
    for (;;) {
      // I really do *not* understand why this check is necessary
      // but it is, at least with JDK 1.6. According to the source code
      // and the javadocs, one would think that join() would exit immediately
      // if the thread is dead. However, I can tell you from experimentation
      // that this is not the case. :-( djp 2008-12-08
      if (!thread.isAlive()) {
        break;
      }
      try {
        thread.join(incrementalWait);
      } catch (InterruptedException e) {
        fail("interrupted");
      }
      if (System.currentTimeMillis() >= tilt) {
        break;
      }
    } // for
    if (thread.isAlive()) {
      logger.info("HUNG THREAD");
      ThreadUtils.dumpStackTrace(thread, thread.getStackTrace());
      ThreadUtils.dumpMyThreads();
      thread.interrupt(); // We're in trouble!
      fail("Thread did not terminate after " + timeoutMilliseconds + " ms: " + thread);
    }
    long elapsedMs = (System.currentTimeMillis() - start);
    if (elapsedMs > 0) {
      String msg = "Thread " + thread + " took " + elapsedMs + " ms to exit.";
      logger.info(msg);
    }
  }
}
