// Copyright 2015 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.model;

import static com.google.testing.junit.runner.util.TestPropertyExporter.INITIAL_INDEX_FOR_REPEATED_PROPERTY;

import com.google.testing.junit.runner.model.TestResult.Status;
import com.google.testing.junit.runner.util.TestIntegration;
import com.google.testing.junit.runner.util.TestIntegrationsExporter;
import com.google.testing.junit.runner.util.TestPropertyExporter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap;
import javax.annotation.Nullable;
import org.junit.runner.Description;

/** A leaf in the test suite model. */
class TestCaseNode extends TestNode
    implements TestPropertyExporter.Callback, TestIntegrationsExporter.Callback {
  private static final Set<State> INITIAL_STATES = Collections.unmodifiableSet(
      EnumSet.of(State.INITIAL, State.PENDING));
  private final TestSuiteNode parent;
  private final Map<String, String> properties = new ConcurrentHashMap<>();
  private final Map<String, Integer> repeatedPropertyNamesToRepetitions = new HashMap<>();
  private final Queue<Throwable> globalFailures = new ConcurrentLinkedQueue<>();
  private final ConcurrentMap<Description, List<Throwable>> dynamicTestToFailures =
      new ConcurrentHashMap<>();
  private final Set<TestIntegration> integrations =
      Collections.newSetFromMap(new ConcurrentHashMap<TestIntegration, Boolean>());

  @Nullable private volatile TestInterval runTimeInterval = null;
  private volatile State state = State.INITIAL;

  TestCaseNode(Description description, TestSuiteNode parent) {
    super(description);
    this.parent = parent;
  }

  // VisibleForTesting
  @Override
  public List<TestNode> getChildren() {
    return Collections.emptyList();
  }

  /**
   * Indicates that the test represented by this node is scheduled to start.
   */
  void pending() {
    compareAndSetState(State.INITIAL, State.PENDING, -1);
  }

  /**
   * Indicates that the test represented by this node has started.
   *
   * @param now Time that the test started
   */
  public void started(long now) {
    compareAndSetState(INITIAL_STATES, State.STARTED, now);
  }

  @Override
  public void testInterrupted(long now) {
    if (compareAndSetState(State.STARTED, State.INTERRUPTED, now)) {
      globalFailures.add(new Exception("Test interrupted"));
      return;
    }
    if (compareAndSetState(INITIAL_STATES, State.CANCELLED, now)) {
      globalFailures.add(new Exception("Test cancelled"));
    }
  }

  @Override
  public void exportProperty(String name, String value) {
    properties.put(name, value);
  }

  @Override
  public String exportRepeatedProperty(String name, String value) {
    String propertyName = getRepeatedPropertyName(name);
    properties.put(propertyName, value);
    return propertyName;
  }

  @Override
  public void exportTestIntegration(TestIntegration testIntegration) {
    integrations.add(testIntegration);
  }

  @Override
  public void testSkipped(long now) {
    compareAndSetState(State.STARTED, State.SKIPPED, now);
  }


  @Override
  public void testSuppressed(long now) {
    compareAndSetState(INITIAL_STATES, State.SUPPRESSED, now);
  }

  /**
   * Indicates that the test represented by this node has finished.
   *
   * @param now Time that the test finished
   */
  public void finished(long now) {
    compareAndSetState(State.STARTED, State.FINISHED, now);
  }

  @Override
  public void testFailure(Throwable throwable, long now) {
    compareAndSetState(INITIAL_STATES, State.FINISHED, now);
    globalFailures.add(throwable);
  }

  @Override
  public void dynamicTestFailure(Description test, Throwable throwable, long now) {
    compareAndSetState(INITIAL_STATES, State.FINISHED, now);
    addThrowableToDynamicTestToFailures(test, throwable);
  }

  private String getRepeatedPropertyName(String name) {
    int index = addNameToRepeatedPropertyNamesAndGetRepetitionsNr(name)
        + INITIAL_INDEX_FOR_REPEATED_PROPERTY;
    return name + index;
  }

  @Override
  public boolean isTestCase() {
    return true;
  }

  private synchronized void addThrowableToDynamicTestToFailures(
      Description test, Throwable throwable) {
    List<Throwable> throwables = dynamicTestToFailures.get(test);
    if (throwables == null) {
      throwables = new ArrayList<>();
      dynamicTestToFailures.put(test, throwables);
    }
    throwables.add(throwable);
  }

  private synchronized int addNameToRepeatedPropertyNamesAndGetRepetitionsNr(String name) {
    Integer previousRepetitionsNr = repeatedPropertyNamesToRepetitions.get(name);
    if (previousRepetitionsNr == null) {
      previousRepetitionsNr = 0;
    }
    repeatedPropertyNamesToRepetitions.put(name, previousRepetitionsNr + 1);
    return previousRepetitionsNr;
  }

  private boolean compareAndSetState(State fromState, State toState, long now) {
    if (fromState == null) {
      throw new NullPointerException();
    }
    return compareAndSetState(Collections.singleton(fromState), toState, now);
  }

  // TODO(bazel-team): Use AtomicReference instead of a synchronized method.
  private synchronized boolean compareAndSetState(Set<State> fromStates, State toState, long now) {
    if (fromStates == null || toState == null || state == null) {
      throw new NullPointerException();
    }
    if (fromStates.isEmpty()) {
      throw new IllegalArgumentException();
    }

    if (fromStates.contains(state) && toState != state) {
      state = toState;
      if (toState != State.PENDING) {
        runTimeInterval =
            runTimeInterval == null
            ? new TestInterval(now, now)
            : runTimeInterval.withEndMillis(now);
      }
      return true;
    }
    return false;
  }

  @Nullable
  public TestInterval getRuntime() {
    return runTimeInterval;
  }

  /**
   * @return The equivalent {@link TestResult.Status} if the test execution ends with the FSM
   *      at this state.
   */
  public TestResult.Status getTestResultStatus() {
    return state.getTestResultStatus();
  }

  @Override
  protected TestResult buildResult() {
    // Some test descriptions, like those provided by JavaScript tests, are
    // constructed by Description.createSuiteDescription, not
    // createTestDescription, because they don't have a "class" per se.
    // In this case, getMethodName returns null and we fill in the className
    // attribute with the name of the parent test suite.
    String name = getDescription().getMethodName();
    String className = getDescription().getClassName();
    if (name == null) {
      name = className;
      className = parent.getDescription().getDisplayName();
    }

    // For now, we give each dynamic test an empty properties map and the same
    // run time and status as its parent test case, but this may change.
    List<TestResult> childResults = new ArrayList<>();
    for (Description dynamicTest : getDescription().getChildren()) {
      childResults.add(buildDynamicResult(dynamicTest, getRuntime(), getTestResultStatus()));
    }

    int numTests = getDescription().isTest() ? 1 : getDescription().getChildren().size();
    int numFailures = globalFailures.isEmpty() ? dynamicTestToFailures.keySet().size() : numTests;
    return new TestResult.Builder()
        .name(name)
        .className(className)
        .properties(properties)
        .failures(new ArrayList<>(globalFailures))
        .runTimeInterval(getRuntime())
        .status(getTestResultStatus())
        .numTests(numTests)
        .numFailures(numFailures)
        .childResults(childResults)
        .integrations(integrations)
        .build();
  }

  private TestResult buildDynamicResult(
      Description test, @Nullable TestInterval runTime, TestResult.Status status) {
    // The dynamic test fails if the testcase itself fails or there is
    // a dynamic failure specifically for the dynamic test.
    List<Throwable> dynamicFailures = dynamicTestToFailures.get(test);
    if (dynamicFailures == null) {
      dynamicFailures = new ArrayList<>();
    }
    boolean failed = !globalFailures.isEmpty() || !dynamicFailures.isEmpty();
    return new TestResult.Builder()
        .name(test.getDisplayName())
        .className(getDescription().getDisplayName())
        .properties(Collections.<String, String>emptyMap())
        .failures(dynamicFailures)
        .runTimeInterval(runTime)
        .status(status)
        .numTests(1)
        .numFailures(failed ? 1 : 0)
        .childResults(Collections.<TestResult>emptyList())
        .integrations(Collections.<TestIntegration>emptySet())
        .build();
  }

  /**
   * States of a TestCaseNode (see (link) for all the transitions and states descriptions).
   */
  private static enum State {
    INITIAL(TestResult.Status.FILTERED),
    PENDING(TestResult.Status.CANCELLED),
    STARTED(TestResult.Status.INTERRUPTED),
    SKIPPED(TestResult.Status.SKIPPED),
    SUPPRESSED(TestResult.Status.SUPPRESSED),
    CANCELLED(TestResult.Status.CANCELLED),
    INTERRUPTED(TestResult.Status.INTERRUPTED),
    FINISHED(TestResult.Status.COMPLETED);

    private final Status status;

    State(TestResult.Status status) {
      this.status = status;
    }

    /**
     * @return The equivalent {@link TestResult.Status} if the test execution ends with the FSM
     *      at this state.
     */
    public TestResult.Status getTestResultStatus() {
      return status;
    }
  }
}
