// Copyright 2017 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.devtools.build.lib.rules.apple;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import javax.annotation.Nullable;

/**
 * Tests that a given comparator (or the implementation of {@link Comparable}) is correct. To use,
 * repeatedly call {@link #addEqualityGroup(Object...)} with sets of objects that should be equal.
 * The calls to {@link #addEqualityGroup(Object...)} must be made in sorted order. Then call {@link
 * #testCompare()} to test the comparison. For example:
 *
 * <pre>{@code
 * new ComparatorTester()
 *     .addEqualityGroup(1)
 *     .addEqualityGroup(2)
 *     .addEqualityGroup(3)
 *     .testCompare();
 * }</pre>
 */
public class ComparatorTester {
  @SuppressWarnings({"unchecked", "rawtypes"})
  private final @Nullable Comparator comparator;

  /** The items that we are checking, stored as a sorted set of equivalence classes. */
  private final List<List<Object>> equalityGroups;

  /**
   * Creates a new instance that tests the order of objects using the natural order (as defined by
   * {@link Comparable}).
   */
  public ComparatorTester() {
    this(null);
  }

  /**
   * Creates a new instance that tests the order of objects using the given comparator. Or, if the
   * comparator is {@code null}, the natural ordering (as defined by {@link Comparable})
   */
  public ComparatorTester(@Nullable Comparator<?> comparator) {
    this.equalityGroups = new ArrayList<>();
    this.comparator = comparator;
  }

  /**
   * Adds a set of objects to the test which should all compare as equal. All of the elements in
   * {@code objects} must be greater than any element of {@code objects} in a previous call to
   * {@link #addEqualityGroup(Object...)}.
   *
   * @return {@code this} (to allow chaining of calls)
   */
  public ComparatorTester addEqualityGroup(Object... objects) {
    Preconditions.checkNotNull(objects);
    Preconditions.checkArgument(objects.length > 0, "Array must not be empty");
    equalityGroups.add(ImmutableList.copyOf(objects));
    return this;
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  private int compare(Object a, Object b) {
    int compareValue;
    if (comparator == null) {
      compareValue = ((Comparable) a).compareTo(b);
    } else {
      compareValue = comparator.compare(a, b);
    }
    return compareValue;
  }

  public final void testCompare() {
    for (int referenceIndex = 0; referenceIndex < equalityGroups.size(); referenceIndex++) {
      for (Object reference : equalityGroups.get(referenceIndex)) {
        testNullCompare(reference);
        testClassCast(reference);
        for (int otherIndex = 0; otherIndex < equalityGroups.size(); otherIndex++) {
          for (Object other : equalityGroups.get(otherIndex)) {
            assertThat(compare(reference, other))
                .isEqualTo(Integer.compare(referenceIndex, otherIndex));
          }
        }
      }
    }
  }

  private void testNullCompare(Object obj) {
    // Comparator does not require any specific behavior for null.
    if (comparator == null) {
      assertThrows(
          "Expected NullPointerException in " + obj + ".compare(null)",
          NullPointerException.class,
          () -> compare(obj, null));
    }
  }

  @SuppressWarnings("unchecked")
  private void testClassCast(Object obj) {
    if (comparator == null) {
      assertThrows(
          "Expected ClassCastException in " + obj + ".compareTo(otherObject)",
          ClassCastException.class,
          () -> compare(obj, ICanNotBeCompared.INSTANCE));
    }
  }

  private static final class ICanNotBeCompared {
    static final ComparatorTester.ICanNotBeCompared INSTANCE = new ICanNotBeCompared();
  }
}
