/*
 * Copyright 2013-present Facebook, Inc.
 *
 * Licensed 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 com.facebook.buck.junit;

import com.facebook.buck.util.concurrent.MoreExecutors;

import org.junit.runner.Description;
import org.junit.runner.Runner;
import org.junit.runner.notification.RunNotifier;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

/**
 * {@link Runner} that composes a {@link Runner} that enforces a default timeout when running a
 * test.
 */
class DelegateRunnerWithTimeout extends Runner {

  /**
   * Shared {@link ExecutorService} on which all tests run by this {@link Runner} are executed.
   * <p>
   * In Robolectric, the {@code ShadowLooper.resetThreadLoopers()} asserts that the current thread
   * is the same as the thread on which the {@code ShadowLooper} class was loaded. Therefore, to
   * preserve the behavior of the {@code org.robolectric.RobolectricTestRunner}, we use an
   * {@link ExecutorService} with a single thread to run all of the tests.
   */
  private static final ExecutorService executor =
      MoreExecutors.newSingleThreadExecutor(DelegateRunnerWithTimeout.class.getSimpleName());

  private final Runner delegate;
  private final long defaultTestTimeoutMillis;

  DelegateRunnerWithTimeout(Runner delegate, long defaultTestTimeoutMillis) {
    if (defaultTestTimeoutMillis <= 0) {
      throw new IllegalArgumentException(String.format(
          "defaultTestTimeoutMillis must be greater than zero but was: %s.",
          defaultTestTimeoutMillis));
    }
    this.delegate = delegate;
    this.defaultTestTimeoutMillis = defaultTestTimeoutMillis;
  }

  /**
   * @return the description from the original {@link Runner} wrapped by this {@link Runner}.
   */
  @Override
  public Description getDescription() {
    return delegate.getDescription();
  }

  /**
   * Runs the tests for this runner, but wraps the specified {@code notifier} with a
   * {@link DelegateRunNotifier} that intercepts calls to the original {@code notifier}.
   * The {@link DelegateRunNotifier} is what enables us to impose our default timeout.
   */
  @Override
  public void run(RunNotifier notifier) {
    final DelegateRunNotifier wrapper = new DelegateRunNotifier(
        delegate, notifier, defaultTestTimeoutMillis);

    // We run the Runner in an Executor so that we can tear it down if we need to.
    Future<?> future = executor.submit(new Runnable() {
      @Override
      public void run() {
        delegate.run(wrapper);
      }
    });

    // We poll the Executor to see if the Runner is complete. In the event that a test has exceeded
    // the default timeout, we cancel the Runner to protect against the case where the test hangs
    // forever.
    while (true) {
      if (future.isDone()) {
        // Normal termination: hooray!
        return;
      } else if (wrapper.hasTestThatExceededTimeout()) {
        // The test results that have been reported to the RunNotifier should still be output, but
        // there may be tests that did not have a chance to run. Unfortunately, we have no way to
        // tell the Runner to cancel only the runaway test.
        executor.shutdownNow();
        return;
      } else {
        // Tests are still running, so wait and try again.
        try {
          Thread.sleep(/* milliseconds */ 250L);
        } catch (InterruptedException e) {
          // Blargh, continue.
        }
      }
    }
  }

}
