// Copyright 2012 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.testing.junit.runner.internal.junit4;

import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.lib.testutil.MoreAsserts.assertThrows;

import java.util.Arrays;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.Test;
import org.junit.internal.AssumptionViolatedException;
import org.junit.runner.Description;
import org.junit.runner.JUnitCore;
import org.junit.runner.Request;
import org.junit.runner.Result;
import org.junit.runner.RunWith;
import org.junit.runner.Runner;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunNotifier;
import org.junit.runner.notification.StoppedByUserException;
import org.junit.runners.JUnit4;
import org.junit.runners.Suite;
import org.junit.runners.model.InitializationError;

/**
 * Tests for {@link CancellableRequestFactory}.
 */
@RunWith(JUnit4.class)
public class CancellableRequestFactoryTest {

  private final CancellableRequestFactory cancellableRequestFactory =
      new CancellableRequestFactory();

  @Test
  public void testCancelRunAfterStarting() throws Exception {
    final CountDownLatch testStartLatch = new CountDownLatch(1);
    final CountDownLatch testContinueLatch = new CountDownLatch(1);
    final AtomicBoolean secondTestRan = new AtomicBoolean(false);

    // Simulates a test that hangs
    FakeRunner blockingRunner = new FakeRunner("blocks", new Runnable() {
      @Override
      public void run() {
        testStartLatch.countDown();
        try {
          testContinueLatch.await(1, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
          Thread.currentThread().interrupt();
          throw new RuntimeException("Timed out waiting for signal to continue test", e);
        }
      }
    });

    // A runner that should never run its test
    FakeRunner secondRunner = new FakeRunner("shouldNotRun", new Runnable() {
      @Override
      public void run() {
        secondTestRan.set(true);
      }
    });

    RunnerSuite fakeSuite = new RunnerSuite(blockingRunner, secondRunner);
    final Request request = cancellableRequestFactory.createRequest(Request.runner(fakeSuite));

    ExecutorService executor = Executors.newSingleThreadExecutor();
    Future<Result> future = executor.submit(new Callable<Result>() {
      @Override
      public Result call() throws Exception {
        JUnitCore core = new JUnitCore();
        return core.run(request);
      }
    });

    // Simulate cancel being called in the middle of the test
    testStartLatch.await(1, TimeUnit.SECONDS);
    cancellableRequestFactory.cancelRun();
    testContinueLatch.countDown();

    ExecutionException e =
        assertThrows(ExecutionException.class, () -> future.get(10, TimeUnit.SECONDS));
    Throwable runnerException = e.getCause();
      assertThat(runnerException).isInstanceOf(RuntimeException.class);
      assertThat(runnerException).hasMessageThat().isEqualTo("Test run interrupted");
    assertThat(runnerException).hasCauseThat().isInstanceOf(StoppedByUserException.class);

    executor.shutdownNow();
  }

  @Test
  public void testCancelRunBeforeStarting() throws Exception {
    final AtomicBoolean testRan = new AtomicBoolean(false);

    // A runner that should never run its test
    FakeRunner runner = new FakeRunner("shouldNotRun", new Runnable() {
      @Override
      public void run() {
        testRan.set(true);
      }
    });

    Request request = cancellableRequestFactory.createRequest(Request.runner(runner));
    cancellableRequestFactory.cancelRun();
    JUnitCore core = new JUnitCore();

    RuntimeException e = assertThrows(RuntimeException.class, () -> core.run(request));
    assertThat(e).hasMessageThat().isEqualTo("Test run interrupted");
    assertThat(e).hasCauseThat().isInstanceOf(StoppedByUserException.class);

    assertThat(testRan.get()).isFalse();
  }

  @Test
  public void testNormalRun() {
    final AtomicBoolean testRan = new AtomicBoolean(false);

    // A runner that should run its test
    FakeRunner runner = new FakeRunner("shouldRun", new Runnable() {
      @Override
      public void run() {
        testRan.set(true);
      }
    });

    Request request = cancellableRequestFactory.createRequest(Request.runner(runner));
    JUnitCore core = new JUnitCore();
    Result result = core.run(request);

    assertThat(testRan.get()).isTrue();
    assertThat(result.getRunCount()).isEqualTo(1);
    assertThat(result.getFailureCount()).isEqualTo(0);
  }

  @Test
  public void testFailingRun() {
    final AtomicBoolean testRan = new AtomicBoolean(false);
    final RuntimeException expectedFailure = new RuntimeException();

    // A runner that should run its test
    FakeRunner runner = new FakeRunner("shouldRun", new Runnable() {
      @Override
      public void run() {
        testRan.set(true);
        throw expectedFailure;
      }
    });

    Request request = cancellableRequestFactory.createRequest(Request.runner(runner));
    JUnitCore core = new JUnitCore();
    Result result = core.run(request);

    assertThat(testRan.get()).isTrue();
    assertThat(result.getRunCount()).isEqualTo(1);
    assertThat(result.getFailureCount()).isEqualTo(1);
    assertThat(result.getFailures().get(0).getException()).isSameInstanceAs(expectedFailure);
  }


  private static class FakeRunner extends Runner {
    private final Description testDescription;
    private final Runnable test;

    public FakeRunner(String testName, Runnable test) {
      this.test = test;
      testDescription = Description.createTestDescription(FakeRunner.class, testName);
    }

    @Override
    public Description getDescription() {
      return testDescription;
    }

    @Override
    public void run(RunNotifier notifier) {
      notifier.fireTestStarted(testDescription);

      try {
        test.run();
      } catch (AssumptionViolatedException e) {
        notifier.fireTestAssumptionFailed(new Failure(testDescription, e));
      } catch (Throwable e) {
        notifier.fireTestFailure(new Failure(testDescription, e));
      } finally {
        notifier.fireTestFinished(testDescription);
      }
    }
  }

  public static class FakeSuite {
  }

  public static class RunnerSuite extends Suite {

    public RunnerSuite(Runner... runners) throws InitializationError {
      super(FakeSuite.class, Arrays.asList(runners));
    }
  }
}
