/*
 * Copyright (C) 2008 The Guava Authors
 *
 * 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.common.collect.testing;

import com.google.common.annotations.GwtCompatible;
import com.google.errorprone.annotations.OverridingMethodsMustInvokeSuper;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.junit.Ignore;

/**
 * Base class for testers of classes (including {@link Collection} and {@link java.util.Map Map})
 * that contain elements.
 *
 * @param <C> the type of the container
 * @param <E> the type of the container's contents
 * @author George van den Driessche
 */
@GwtCompatible
@Ignore // Affects only Android test runner, which respects JUnit 4 annotations on JUnit 3 tests.
public abstract class AbstractContainerTester<C, E>
    extends AbstractTester<OneSizeTestContainerGenerator<C, E>> {
  protected SampleElements<E> samples;
  protected C container;

  @Override
  @OverridingMethodsMustInvokeSuper
  public void setUp() throws Exception {
    super.setUp();
    samples = this.getSubjectGenerator().samples();
    resetContainer();
  }

  /**
   * @return the contents of the container under test, for use by {@link #expectContents(Object[])
   *     expectContents(E...)} and its friends.
   */
  protected abstract Collection<E> actualContents();

  /**
   * Replaces the existing container under test with a new container created by the subject
   * generator.
   *
   * @see #resetContainer(Object) resetContainer(C)
   * @return the new container instance.
   */
  protected C resetContainer() {
    return resetContainer(getSubjectGenerator().createTestSubject());
  }

  /**
   * Replaces the existing container under test with a new container. This is useful when a single
   * test method needs to create multiple containers while retaining the ability to use {@link
   * #expectContents(Object[]) expectContents(E...)} and other convenience methods. The creation of
   * multiple containers in a single method is discouraged in most cases, but it is vital to the
   * iterator tests.
   *
   * @return the new container instance
   * @param newValue the new container instance
   */
  protected C resetContainer(C newValue) {
    container = newValue;
    return container;
  }

  /**
   * @see #expectContents(java.util.Collection)
   * @param elements expected contents of {@link #container}
   */
  protected final void expectContents(E... elements) {
    expectContents(Arrays.asList(elements));
  }

  /**
   * Asserts that the collection under test contains exactly the given elements, respecting
   * cardinality but not order. Subclasses may override this method to provide stronger assertions,
   * e.g., to check ordering in lists, but realize that <strong>unless a test extends {@link
   * com.google.common.collect.testing.testers.AbstractListTester AbstractListTester}, a call to
   * {@code expectContents()} invokes this version</strong>.
   *
   * @param expected expected value of {@link #container}
   */
  /*
   * TODO: improve this and other implementations and move out of this framework
   * for wider use
   *
   * TODO: could we incorporate the overriding logic from AbstractListTester, by
   * examining whether the features include KNOWN_ORDER?
   */
  protected void expectContents(Collection<E> expected) {
    Helpers.assertEqualIgnoringOrder(expected, actualContents());
  }

  protected void expectUnchanged() {
    expectContents(getOrderedElements());
  }

  /**
   * Asserts that the collection under test contains exactly the elements it was initialized with
   * plus the given elements, according to {@link #expectContents(java.util.Collection)}. In other
   * words, for the default {@code expectContents()} implementation, the number of occurrences of
   * each given element has increased by one since the test collection was created, and the number
   * of occurrences of all other elements has not changed.
   *
   * <p>Note: This means that a test like the following will fail if {@code collection} is a {@code
   * Set}:
   *
   * <pre>
   * collection.add(existingElement);
   * expectAdded(existingElement);</pre>
   *
   * <p>In this case, {@code collection} was not modified as a result of the {@code add()} call, and
   * the test will fail because the number of occurrences of {@code existingElement} is unchanged.
   *
   * @param elements expected additional contents of {@link #container}
   */
  protected final void expectAdded(E... elements) {
    List<E> expected = Helpers.copyToList(getSampleElements());
    expected.addAll(Arrays.asList(elements));
    expectContents(expected);
  }

  protected final void expectAdded(int index, E... elements) {
    expectAdded(index, Arrays.asList(elements));
  }

  protected final void expectAdded(int index, Collection<E> elements) {
    List<E> expected = Helpers.copyToList(getSampleElements());
    expected.addAll(index, elements);
    expectContents(expected);
  }

  /*
   * TODO: if we're testing a list, we could check indexOf(). (Doing it in
   * AbstractListTester isn't enough because many tests that run on lists don't
   * extends AbstractListTester.) We could also iterate over all elements to
   * verify absence
   */
  protected void expectMissing(E... elements) {
    for (E element : elements) {
      assertFalse("Should not contain " + element, actualContents().contains(element));
    }
  }

  protected E[] createSamplesArray() {
    E[] array = getSubjectGenerator().createArray(getNumElements());
    getSampleElements().toArray(array);
    return array;
  }

  protected E[] createOrderedArray() {
    E[] array = getSubjectGenerator().createArray(getNumElements());
    getOrderedElements().toArray(array);
    return array;
  }

  public static class ArrayWithDuplicate<E> {
    public final E[] elements;
    public final E duplicate;

    private ArrayWithDuplicate(E[] elements, E duplicate) {
      this.elements = elements;
      this.duplicate = duplicate;
    }
  }

  /**
   * @return an array of the proper size with a duplicate element. The size must be at least three.
   */
  protected ArrayWithDuplicate<E> createArrayWithDuplicateElement() {
    E[] elements = createSamplesArray();
    E duplicate = elements[(elements.length / 2) - 1];
    elements[(elements.length / 2) + 1] = duplicate;
    return new ArrayWithDuplicate<E>(elements, duplicate);
  }

  // Helper methods to improve readability of derived classes

  protected int getNumElements() {
    return getSubjectGenerator().getCollectionSize().getNumElements();
  }

  protected Collection<E> getSampleElements(int howMany) {
    return getSubjectGenerator().getSampleElements(howMany);
  }

  protected Collection<E> getSampleElements() {
    return getSampleElements(getNumElements());
  }

  /**
   * Returns the {@linkplain #getSampleElements() sample elements} as ordered by {@link
   * TestContainerGenerator#order(List)}. Tests should used this method only if they declare
   * requirement {@link com.google.common.collect.testing.features.CollectionFeature#KNOWN_ORDER}.
   */
  protected List<E> getOrderedElements() {
    List<E> list = new ArrayList<E>();
    for (E e : getSubjectGenerator().order(new ArrayList<E>(getSampleElements()))) {
      list.add(e);
    }
    return Collections.unmodifiableList(list);
  }

  /**
   * @return a suitable location for a null element, to use when initializing containers for tests
   *     that involve a null element being present.
   */
  protected int getNullLocation() {
    return getNumElements() / 2;
  }

  @SuppressWarnings("unchecked")
  protected MinimalCollection<E> createDisjointCollection() {
    return MinimalCollection.of(e3(), e4());
  }

  @SuppressWarnings("unchecked")
  protected MinimalCollection<E> emptyCollection() {
    return MinimalCollection.<E>of();
  }

  protected final E e0() {
    return samples.e0();
  }

  protected final E e1() {
    return samples.e1();
  }

  protected final E e2() {
    return samples.e2();
  }

  protected final E e3() {
    return samples.e3();
  }

  protected final E e4() {
    return samples.e4();
  }
}
