// Copyright 2014 The Bazel Authors. All rights reserved.
//
// 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.google.devtools.build.skyframe;

import static com.google.common.truth.Truth.assertThat;

import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.Uninterruptibles;
import com.google.devtools.build.lib.testutil.TestUtils;
import com.google.devtools.build.lib.util.Pair;

import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * Safely await {@link CountDownLatch}es in tests, storing any exceptions that happen. Callers
 * should call {@link #assertNoErrors} at the end of each test method, either manually or using an
 * {@code @After} hook.
 */
public class TrackingAwaiter {
  public static final TrackingAwaiter INSTANCE = new TrackingAwaiter();

  private TrackingAwaiter() {}

  private final ConcurrentLinkedQueue<Pair<String, Throwable>> exceptionsThrown =
      new ConcurrentLinkedQueue<>();

  /**
   * This method fixes a race condition with simply calling {@link CountDownLatch#await}. If this
   * thread is interrupted before {@code latch.await} is called, then {@code latch.await} will throw
   * an {@link InterruptedException} without checking the value of the latch at all. This leads to a
   * race condition in which this thread will throw an InterruptedException if it is slow calling
   * {@code latch.await}, but it will succeed normally otherwise.
   *
   * <p>To avoid this, we wait for the latch uninterruptibly. In the end, if the latch has in fact
   * been released, we do nothing, although the interrupted bit is set, so that the caller can
   * decide to throw an InterruptedException if it wants to. If the latch was not released, then
   * this was not a race condition, but an honest-to-goodness interrupt, and we propagate the
   * exception onward.
   */
  private static void waitAndMaybeThrowInterrupt(CountDownLatch latch, String errorMessage)
      throws InterruptedException {
    if (Uninterruptibles.awaitUninterruptibly(latch, TestUtils.WAIT_TIMEOUT_SECONDS,
        TimeUnit.SECONDS)) {
      // Latch was released. We can ignore the interrupt state.
      return;
    }
    if (!Thread.currentThread().isInterrupted()) {
      // Nobody interrupted us, but latch wasn't released. Failure.
      throw new AssertionError(errorMessage);
    } else {
      // We were interrupted before the latch was released. Propagate this interruption.
      throw new InterruptedException();
    }
  }

  /** Threadpools can swallow exceptions. Make sure they don't get lost. */
  public void awaitLatchAndTrackExceptions(CountDownLatch latch, String errorMessage) {
    try {
      waitAndMaybeThrowInterrupt(latch, errorMessage);
    } catch (Throwable e) {
      // We would expect e to be InterruptedException or AssertionError, but we leave it open so
      // that any throwable gets recorded.
      exceptionsThrown.add(Pair.of(errorMessage, e));
      // Caller will assert exceptionsThrown is empty at end of test and fail, even if this is
      // swallowed.
      Throwables.propagate(e);
    }
  }

  /** Allow arbitrary errors to be recorded here for later throwing. */
  public void injectExceptionAndMessage(Throwable throwable, String message) {
    exceptionsThrown.add(Pair.of(message, throwable));
  }

  public void assertNoErrors() {
    List<Pair<String, Throwable>> thisEvalExceptionsThrown = ImmutableList.copyOf(exceptionsThrown);
    exceptionsThrown.clear();
    assertThat(thisEvalExceptionsThrown).isEmpty();
  }
}
