/**
 * @license
 * Copyright 2013 Google Inc. 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.security.wycheproof;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Arrays;
import org.junit.runner.Description;
import org.junit.runner.manipulation.Filter;
import org.junit.runner.manipulation.NoTestsRemainException;
import org.junit.runners.Suite;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.RunnerBuilder;

/**
 * <p>A custom JUnit4 runner that, with annotations, allows choosing tests to run on a specific
 * provider. To use it, annotate a runner class with {@code RunWith(WycheproofRunner.class)}, and
 * {@code SuiteClasses({AesGcmTest.class, ...})}. When you run this class, it will run all the tests
 * in all the suite classes.
 *
 * <p>To exclude certain tests, a runner class should be annotated with {@code @Provider} which
 * indicates the target provider. Test exclusion is defined as follows:
 * <ul>@Fast test runners skip @SlowTest test functions.
 * <ul>@Presubmit test runners skip @NoPresubmitTest test functions.
 * <ul>All test runners skip @ExcludedTest test functions.
 *
 * @author thaidn@google.com (Thai Duong)
 */
public class WycheproofRunner extends Suite {

  /** List of supported providers. */
  public enum ProviderType {
    BOUNCY_CASTLE,
    CONSCRYPT,
    OPENJDK,
    SPONGY_CASTLE,
  }

  // Annotations for test runners.

  /**
   * Annotation to specify the target provider of a test runner.
   *
   * <p>Usage: @Provider(ProviderType.BOUNCY_CASTLE)
   */
  @Retention(RetentionPolicy.RUNTIME)
  @Target({ElementType.TYPE})
  public @interface Provider {
    ProviderType value();
  }

  /**
   * Annotation to specify presubmit test runners that exclude {@code @NoPresubmitTets} tests.
   *
   * <p>Usage: @Presubmit(ProviderType.BOUNCY_CASTLE)
   */
  @Retention(RetentionPolicy.RUNTIME)
  @Target({ElementType.TYPE})
  public @interface Presubmit {}

  /**
   * Annotation to specify fast test runners that exclude {@code @SlowTest} tests.
   *
   * <p>Usage: @Fast
   */
  @Retention(RetentionPolicy.RUNTIME)
  @Target({ElementType.TYPE})
  public @interface Fast {}

  // Annotations for test functions

  /**
   * Tests that take too much time to run, should be excluded from TAP and wildcard target patterns
   * like:..., :*, or :all.
   *
   * <p>Usage: @SlowTest(providers = {ProviderType.BOUNCY_CASTLE, ...})
   */
  @Retention(RetentionPolicy.RUNTIME)
  @Target({ElementType.METHOD})
  public @interface SlowTest {
    ProviderType[] providers();
  }

  /**
   * Tests that should be excluded from presubmit checks on specific providers.
   *
   * <p>Usage: @NoPresubmitTest(
   *   providers = {ProviderType.BOUNCY_CASTLE, ...},
   *   bugs = {"b/123456789"}
   * )
   */
  @Retention(RetentionPolicy.RUNTIME)
  @Target({ElementType.METHOD, ElementType.FIELD})
  public @interface NoPresubmitTest {
    /** List of providers that this test method should not run as presubmit check. */
    ProviderType[] providers();

    /** List of blocking bugs (and comments). */
    String[] bugs();
  }

  /**
   * Annotation to specify test functions that should be excluded on specific providers.
   *
   * <p>Usage: @ExcludedTest(providers = {ProviderType.BOUNCY_CASTLE, ProviderType.OPENJDK})
   */
  @Retention(RetentionPolicy.RUNTIME)
  @Target({ElementType.METHOD})
  public @interface ExcludedTest {
    ProviderType[] providers();
    String comment();
  }

  /**
   * Custom filter to exclude certain test functions.
   *
   */
  public static class ExcludeTestFilter extends Filter {

    Class<?> runnerClass;
    Provider targetProvider;
    Fast fast;
    Presubmit presubmit;

    public ExcludeTestFilter(Class<?> runnerClass) {
      this.runnerClass = runnerClass;
      this.targetProvider = runnerClass.getAnnotation(Provider.class);
      this.fast = runnerClass.getAnnotation(Fast.class);
      this.presubmit = runnerClass.getAnnotation(Presubmit.class);
    }

    @Override
    public String describe() {
      return "exclude certain tests on specific providers";
    }

    @Override
    public boolean shouldRun(Description description) {
      return isOkayToRunTest(description);
    }

    private boolean isOkayToRunTest(Description description) {
      if (targetProvider == null) {
        // Run all test functions if the test runner is not annotated with {@code @Provider}.
        return true;
      }
      // Skip @ExcludedTest tests
      ExcludedTest excludedTest = description.getAnnotation(ExcludedTest.class);
      if (excludedTest != null
          && Arrays.asList(excludedTest.providers()).contains(targetProvider.value())) {
        return false;
      }

      // If the runner class is annotated with @Presubmit, skip non-presubmit tests
      if (presubmit != null) {
        NoPresubmitTest ignoreOn = description.getAnnotation(NoPresubmitTest.class);
        if (ignoreOn != null
            && Arrays.asList(ignoreOn.providers()).contains(targetProvider.value())) {
          return false;
        }
      }

      // If the runner class is annotated with @Fast, skip slow tests
      if (fast != null) {
        SlowTest ignoreOn = description.getAnnotation(SlowTest.class);
        if (ignoreOn != null
            && Arrays.asList(ignoreOn.providers()).contains(targetProvider.value())) {
          return false;
        }
      }

      // run everything else
      return true;
    }
  }

  /** Required constructor: called by JUnit reflectively. */
  public WycheproofRunner(Class<?> runnerClass, RunnerBuilder builder) throws InitializationError {
    super(runnerClass, builder);
    addFilter(new ExcludeTestFilter(runnerClass));
  }

  private void addFilter(Filter filter) {
    try {
      filter(filter);
    } catch (NoTestsRemainException ex) {
      System.out.println("No tests remain exception: " + ex);
    }
  }
}
