// 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 org.junit.Assert.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));
    }
  }
}
