// Copyright 2010 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.junit4;

import com.google.testing.junit.junit4.runner.RegExTestCaseFilter;
import com.google.testing.junit.junit4.runner.SuiteTrimmingFilter;
import com.google.testing.junit.runner.internal.Stdout;
import com.google.testing.junit.runner.internal.junit4.CancellableRequestFactory;
import com.google.testing.junit.runner.model.TestSuiteModel;
import com.google.testing.junit.runner.util.GoogleTestSecurityManager;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Set;
import java.util.function.Supplier;
import javax.annotation.Nullable;
import javax.inject.Inject;
import org.junit.internal.runners.ErrorReportingRunner;
import org.junit.runner.Description;
import org.junit.runner.JUnitCore;
import org.junit.runner.Request;
import org.junit.runner.Result;
import org.junit.runner.Runner;
import org.junit.runner.manipulation.Filter;
import org.junit.runner.manipulation.NoTestsRemainException;
import org.junit.runner.notification.RunListener;
import org.junit.runner.notification.RunNotifier;

/**
 * Main entry point for running JUnit4 tests.<p>
 */
public class JUnit4Runner {
  private final Request request;
  private final CancellableRequestFactory requestFactory;
  private final Supplier<TestSuiteModel> modelSupplier;
  private final PrintStream testRunnerOut;
  private final JUnit4Config config;
  private final Set<RunListener> runListeners;
  private final Set<Initializer> initializers;

  private GoogleTestSecurityManager googleTestSecurityManager;
  private SecurityManager previousSecurityManager;

  /**
   * Creates a runner.
   */
  @Inject
  JUnit4Runner(
      Request request,
      CancellableRequestFactory requestFactory,
      Supplier<TestSuiteModel> modelSupplier,
      @Stdout PrintStream testRunnerOut,
      JUnit4Config config,
      Set<RunListener> runListeners,
      Set<Initializer> initializers) {
    this.request = request;
    this.requestFactory = requestFactory;
    this.modelSupplier = modelSupplier;
    this.config = config;
    this.testRunnerOut = testRunnerOut;
    this.runListeners = runListeners;
    this.initializers = initializers;
  }

  /**
   * Runs the JUnit4 test.
   *
   * @return Result of running the test
   */
  public Result run() {
    testRunnerOut.println("JUnit4 Test Runner");
    checkJUnitRunnerApiVersion();

    for (Initializer init : initializers) {
      init.initialize();
    }

    // Sharding
    TestSuiteModel model = modelSupplier.get();
    Filter shardingFilter = model.getShardingFilter();

    Request filteredRequest = applyFilters(request, shardingFilter,
        config.getTestIncludeFilterRegexp(),
        config.getTestExcludeFilterRegexp());

    JUnitCore core = new JUnitCore();
    for (RunListener runListener : runListeners) {
      core.addListener(runListener);
    }

    File exitFile = getExitFile();
    exitFileActive(exitFile);
    try {
      try {
        if (config.shouldInstallSecurityManager()) {
          installSecurityManager();
        }
        Request cancellableRequest = requestFactory.createRequest(filteredRequest);
        return core.run(cancellableRequest);
      } finally {
        disableSecurityManager();
      }
    } finally {
      exitFileInactive(exitFile);
    }
  }

  // Support for "premature exit files": Tests may write this to communicate
  // to the runner in case of premature exit.
  private static File getExitFile() {
    String exitFile = System.getenv("TEST_PREMATURE_EXIT_FILE");
    return exitFile == null ? null : new File(exitFile);
  }

  private static void exitFileActive(@Nullable File file) {
    if (file != null) {
      try (FileOutputStream outputStream = new FileOutputStream(file, false)) {
        // Overwrite file content.
        outputStream.write(new byte[0]);
        outputStream.close();
      } catch (IOException e) {
        throw new RuntimeException("Could not write exit file at " + file, e);
      }
    }
  }

  private void exitFileInactive(@Nullable File file) {
    if (file != null) {
      try {
        file.delete();
      } catch (Throwable t) {
        // Just print the stack trace, to avoid masking a real test failure.
        t.printStackTrace(testRunnerOut);
      }
    }
  }

  // VisibleForTesting
  TestSuiteModel getModel() {
    return modelSupplier.get();
  }

  private static Request applyFilter(Request request, Filter filter)
      throws NoTestsRemainException {
    Runner runner = request.getRunner();
    new SuiteTrimmingFilter(filter).apply(runner);
    return Request.runner(runner);
  }

  /**
   * Apply command-line and sharding filters, if appropriate.<p>
   *
   * Note that this is carefully written to avoid running into potential
   * problems with the way runners implement filtering. The JavaDoc for
   * {@link org.junit.runner.manipulation.Filterable} states that tests that
   * don't match the filter should be removed, which implies if you apply two
   * filters, you will always get an intersection of the two. Unfortunately, the
   * filtering implementation of {@link org.junit.runners.ParentRunner} does not
   * do this, and instead uses a "last applied filter wins" strategy.<p>
   *
   * We work around potential problems by ensuring that if we apply a second
   * filter, the filter is more restrictive than the first. We also assume that
   * if filtering fails, the request will have a runner that is a
   * {@link ErrorReportingRunner}. Luckily, we can cover this with tests to make
   * sure we don't break if JUnit changes in the future.
   *
   * @param request Request to filter
   * @param shardingFilter Sharding filter to use; {@link Filter#ALL} to not do sharding
   * @param testIncludeFilterRegexp String denoting a regular expression with which
   *     to filter tests.  Only test descriptions that match this regular
   *     expression will be run.  If {@code null}, tests will not be filtered.
   * @param testExcludeFilterRegexp String denoting a regular expression with which
   *     to filter tests.  Only test descriptions that do not match this regular
   *     expression will be run.  If {@code null}, tests will not be filtered.
   * @return Filtered request (may be a request that delegates to
   *         {@link ErrorReportingRunner}
   */
  private static Request applyFilters(Request request, Filter shardingFilter,
      @Nullable String testIncludeFilterRegexp, @Nullable String testExcludeFilterRegexp) {
    // Allow the user to specify a filter on the command line
    boolean allowNoTests = false;
    Filter filter = Filter.ALL;
    if (testIncludeFilterRegexp != null) {
      filter = RegExTestCaseFilter.include(testIncludeFilterRegexp);
    }

    if (testExcludeFilterRegexp != null) {
      Filter excludeFilter = RegExTestCaseFilter.exclude(testExcludeFilterRegexp);
      filter = filter.intersect(excludeFilter);
    }

    if (testIncludeFilterRegexp != null || testExcludeFilterRegexp != null) {
      try {
        request = applyFilter(request, filter);
      } catch (NoTestsRemainException e) {
        return createErrorReportingRequestForFilterError(filter);
      }

      /*
       * If you filter a sharded test to run one test, we don't want all the
       * shards but one to fail.
       */
      allowNoTests = (shardingFilter != Filter.ALL);
    }

    // Sharding
    if (shardingFilter != Filter.ALL) {
      filter = filter.intersect(shardingFilter);
    }

    if (filter != Filter.ALL) {
      try {
        request = applyFilter(request, filter);
      } catch (NoTestsRemainException e) {
        if (allowNoTests) {
          return Request.runner(new NoOpRunner());
        } else {
          return createErrorReportingRequestForFilterError(filter);
        }
      }
    }
    return request;
  }

  @SuppressWarnings({"ThrowableInstanceNeverThrown"})
  private static Request createErrorReportingRequestForFilterError(Filter filter) {
    ErrorReportingRunner runner = new ErrorReportingRunner(Filter.class, new Exception(
        String.format("No tests found matching %s", filter.describe())));
    return Request.runner(runner);
  }

  private void checkJUnitRunnerApiVersion() {
    config.getJUnitRunnerApiVersion();
  }

  private void installSecurityManager() {
    previousSecurityManager = System.getSecurityManager();
    GoogleTestSecurityManager newSecurityManager = new GoogleTestSecurityManager();
    System.setSecurityManager(newSecurityManager);

    // set field after call to setSecurityManager() in case that call fails
    googleTestSecurityManager = newSecurityManager;
  }

  private void disableSecurityManager() {
    if (googleTestSecurityManager != null) {
      GoogleTestSecurityManager.uninstallIfInstalled();
      System.setSecurityManager(previousSecurityManager);
    }
  }

  static class NoOpRunner extends Runner {
    @Override
    public Description getDescription() {
      return Description.createTestDescription(getClass(), "nothingToDo");
    }

    @Override
    public void run(RunNotifier notifier) {
    }
  }

  /**
   * A simple initializer which can be used to provide additional initialization logic in custom
   * runners.
   *
   * <p>Initializers will be run in unspecified order. If an exception is thrown it will not be
   * deemed recoverable and will cause the runner to error-out.
   */
  public interface Initializer {
    void initialize();
  }
}
