/*
 * 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.logging.internal.log4j.api.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);
    }
  }
}
