/*
 * 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;

import static com.google.common.collect.Iterables.concat;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Lists.newLinkedList;
import static com.google.common.truth.Truth.assertThat;
import static java.util.Arrays.asList;
import static java.util.Collections.nCopies;

import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.testing.CollectionTestSuiteBuilder;
import com.google.common.collect.testing.TestStringCollectionGenerator;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.testing.NullPointerTester;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
 * Tests for {@link Collections2}.
 *
 * @author Chris Povirk
 * @author Jared Levy
 */
@GwtCompatible(emulated = true)
public class Collections2Test extends TestCase {
  @GwtIncompatible // suite
  public static Test suite() {
    TestSuite suite = new TestSuite(Collections2Test.class.getSimpleName());
    suite.addTest(testsForFilter());
    suite.addTest(testsForFilterAll());
    suite.addTest(testsForFilterLinkedList());
    suite.addTest(testsForFilterNoNulls());
    suite.addTest(testsForFilterFiltered());
    suite.addTest(testsForTransform());
    suite.addTestSuite(Collections2Test.class);
    return suite;
  }

  static final Predicate<String> NOT_YYY_ZZZ =
      new Predicate<String>() {
        @Override
        public boolean apply(String input) {
          return !"yyy".equals(input) && !"zzz".equals(input);
        }
      };

  static final Predicate<String> LENGTH_1 =
      new Predicate<String>() {
        @Override
        public boolean apply(String input) {
          return input.length() == 1;
        }
      };

  static final Predicate<String> STARTS_WITH_VOWEL =
      new Predicate<String>() {
        @Override
        public boolean apply(String input) {
          return asList('a', 'e', 'i', 'o', 'u').contains(input.charAt(0));
        }
      };

  @GwtIncompatible // suite
  private static Test testsForFilter() {
    return CollectionTestSuiteBuilder.using(
            new TestStringCollectionGenerator() {
              @Override
              public Collection<String> create(String[] elements) {
                List<String> unfiltered = newArrayList();
                unfiltered.add("yyy");
                Collections.addAll(unfiltered, elements);
                unfiltered.add("zzz");
                return Collections2.filter(unfiltered, NOT_YYY_ZZZ);
              }
            })
        .named("Collections2.filter")
        .withFeatures(
            CollectionFeature.SUPPORTS_ADD,
            CollectionFeature.SUPPORTS_REMOVE,
            CollectionFeature.ALLOWS_NULL_VALUES,
            CollectionFeature.KNOWN_ORDER,
            CollectionSize.ANY)
        .createTestSuite();
  }

  @GwtIncompatible // suite
  private static Test testsForFilterAll() {
    return CollectionTestSuiteBuilder.using(
            new TestStringCollectionGenerator() {
              @Override
              public Collection<String> create(String[] elements) {
                List<String> unfiltered = newArrayList();
                Collections.addAll(unfiltered, elements);
                return Collections2.filter(unfiltered, NOT_YYY_ZZZ);
              }
            })
        .named("Collections2.filter")
        .withFeatures(
            CollectionFeature.SUPPORTS_ADD,
            CollectionFeature.SUPPORTS_REMOVE,
            CollectionFeature.ALLOWS_NULL_VALUES,
            CollectionFeature.KNOWN_ORDER,
            CollectionSize.ANY)
        .createTestSuite();
  }

  @GwtIncompatible // suite
  private static Test testsForFilterLinkedList() {
    return CollectionTestSuiteBuilder.using(
            new TestStringCollectionGenerator() {
              @Override
              public Collection<String> create(String[] elements) {
                List<String> unfiltered = newLinkedList();
                unfiltered.add("yyy");
                Collections.addAll(unfiltered, elements);
                unfiltered.add("zzz");
                return Collections2.filter(unfiltered, NOT_YYY_ZZZ);
              }
            })
        .named("Collections2.filter")
        .withFeatures(
            CollectionFeature.SUPPORTS_ADD,
            CollectionFeature.SUPPORTS_REMOVE,
            CollectionFeature.ALLOWS_NULL_VALUES,
            CollectionFeature.KNOWN_ORDER,
            CollectionSize.ANY)
        .createTestSuite();
  }

  @GwtIncompatible // suite
  private static Test testsForFilterNoNulls() {
    return CollectionTestSuiteBuilder.using(
            new TestStringCollectionGenerator() {
              @Override
              public Collection<String> create(String[] elements) {
                List<String> unfiltered = newArrayList();
                unfiltered.add("yyy");
                unfiltered.addAll(ImmutableList.copyOf(elements));
                unfiltered.add("zzz");
                return Collections2.filter(unfiltered, LENGTH_1);
              }
            })
        .named("Collections2.filter, no nulls")
        .withFeatures(
            CollectionFeature.SUPPORTS_ADD,
            CollectionFeature.SUPPORTS_REMOVE,
            CollectionFeature.ALLOWS_NULL_QUERIES,
            CollectionFeature.KNOWN_ORDER,
            CollectionSize.ANY)
        .createTestSuite();
  }

  @GwtIncompatible // suite
  private static Test testsForFilterFiltered() {
    return CollectionTestSuiteBuilder.using(
            new TestStringCollectionGenerator() {
              @Override
              public Collection<String> create(String[] elements) {
                List<String> unfiltered = newArrayList();
                unfiltered.add("yyy");
                unfiltered.addAll(ImmutableList.copyOf(elements));
                unfiltered.add("zzz");
                unfiltered.add("abc");
                return Collections2.filter(Collections2.filter(unfiltered, LENGTH_1), NOT_YYY_ZZZ);
              }
            })
        .named("Collections2.filter, filtered input")
        .withFeatures(
            CollectionFeature.SUPPORTS_ADD,
            CollectionFeature.SUPPORTS_REMOVE,
            CollectionFeature.KNOWN_ORDER,
            CollectionFeature.ALLOWS_NULL_QUERIES,
            CollectionSize.ANY)
        .createTestSuite();
  }

  private static final Function<String, String> REMOVE_FIRST_CHAR =
      new Function<String, String>() {
        @Override
        public String apply(String from) {
          return ((from == null) || "".equals(from)) ? null : from.substring(1);
        }
      };

  @GwtIncompatible // suite
  private static Test testsForTransform() {
    return CollectionTestSuiteBuilder.using(
            new TestStringCollectionGenerator() {
              @Override
              public Collection<String> create(String[] elements) {
                List<String> list = newArrayList();
                for (String element : elements) {
                  list.add((element == null) ? null : "q" + element);
                }
                return Collections2.transform(list, REMOVE_FIRST_CHAR);
              }
            })
        .named("Collections2.transform")
        .withFeatures(
            CollectionFeature.REMOVE_OPERATIONS,
            CollectionFeature.ALLOWS_NULL_VALUES,
            CollectionFeature.KNOWN_ORDER,
            CollectionSize.ANY)
        .createTestSuite();
  }

  @GwtIncompatible // NullPointerTester
  public void testNullPointerExceptions() {
    NullPointerTester tester = new NullPointerTester();
    tester.testAllPublicStaticMethods(Collections2.class);
  }

  public void testOrderedPermutationSetEmpty() {
    List<Integer> list = newArrayList();
    Collection<List<Integer>> permutationSet = Collections2.orderedPermutations(list);

    assertEquals(1, permutationSet.size());
    assertThat(permutationSet).contains(list);

    Iterator<List<Integer>> permutations = permutationSet.iterator();

    assertNextPermutation(Lists.<Integer>newArrayList(), permutations);
    assertNoMorePermutations(permutations);
  }

  public void testOrderedPermutationSetOneElement() {
    List<Integer> list = newArrayList(1);
    Iterator<List<Integer>> permutations = Collections2.orderedPermutations(list).iterator();

    assertNextPermutation(newArrayList(1), permutations);
    assertNoMorePermutations(permutations);
  }

  public void testOrderedPermutationSetThreeElements() {
    List<String> list = newArrayList("b", "a", "c");
    Iterator<List<String>> permutations = Collections2.orderedPermutations(list).iterator();

    assertNextPermutation(newArrayList("a", "b", "c"), permutations);
    assertNextPermutation(newArrayList("a", "c", "b"), permutations);
    assertNextPermutation(newArrayList("b", "a", "c"), permutations);
    assertNextPermutation(newArrayList("b", "c", "a"), permutations);
    assertNextPermutation(newArrayList("c", "a", "b"), permutations);
    assertNextPermutation(newArrayList("c", "b", "a"), permutations);
    assertNoMorePermutations(permutations);
  }

  public void testOrderedPermutationSetRepeatedElements() {
    List<Integer> list = newArrayList(1, 1, 2, 2);
    Iterator<List<Integer>> permutations =
        Collections2.orderedPermutations(list, Ordering.natural()).iterator();

    assertNextPermutation(newArrayList(1, 1, 2, 2), permutations);
    assertNextPermutation(newArrayList(1, 2, 1, 2), permutations);
    assertNextPermutation(newArrayList(1, 2, 2, 1), permutations);
    assertNextPermutation(newArrayList(2, 1, 1, 2), permutations);
    assertNextPermutation(newArrayList(2, 1, 2, 1), permutations);
    assertNextPermutation(newArrayList(2, 2, 1, 1), permutations);
    assertNoMorePermutations(permutations);
  }

  public void testOrderedPermutationSetRepeatedElementsSize() {
    List<Integer> list = newArrayList(1, 1, 1, 1, 2, 2, 3);
    Collection<List<Integer>> permutations =
        Collections2.orderedPermutations(list, Ordering.natural());

    assertPermutationsCount(105, permutations);
  }

  public void testOrderedPermutationSetSizeOverflow() {
    // 12 elements won't overflow
    assertEquals(
        479001600 /*12!*/,
        Collections2.orderedPermutations(newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12))
            .size());
    // 13 elements overflow an int
    assertEquals(
        Integer.MAX_VALUE,
        Collections2.orderedPermutations(newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13))
            .size());
    // 21 elements overflow a long
    assertEquals(
        Integer.MAX_VALUE,
        Collections2.orderedPermutations(
                newArrayList(
                    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21))
            .size());

    // Almost force an overflow in the binomial coefficient calculation
    assertEquals(
        1391975640 /*C(34,14)*/,
        Collections2.orderedPermutations(concat(nCopies(20, 1), nCopies(14, 2))).size());
    // Do force an overflow in the binomial coefficient calculation
    assertEquals(
        Integer.MAX_VALUE,
        Collections2.orderedPermutations(concat(nCopies(21, 1), nCopies(14, 2))).size());
  }

  public void testOrderedPermutationSetContains() {
    List<Integer> list = newArrayList(3, 2, 1);
    Collection<List<Integer>> permutationSet = Collections2.orderedPermutations(list);

    assertTrue(permutationSet.contains(newArrayList(1, 2, 3)));
    assertTrue(permutationSet.contains(newArrayList(2, 3, 1)));
    assertFalse(permutationSet.contains(newArrayList(1, 2)));
    assertFalse(permutationSet.contains(newArrayList(1, 1, 2, 3)));
    assertFalse(permutationSet.contains(newArrayList(1, 2, 3, 4)));
    assertFalse(permutationSet.contains(null));
  }

  public void testPermutationSetEmpty() {
    Collection<List<Integer>> permutationSet =
        Collections2.permutations(Collections.<Integer>emptyList());

    assertEquals(1, permutationSet.size());
    assertTrue(permutationSet.contains(Collections.<Integer>emptyList()));

    Iterator<List<Integer>> permutations = permutationSet.iterator();
    assertNextPermutation(Collections.<Integer>emptyList(), permutations);
    assertNoMorePermutations(permutations);
  }

  public void testPermutationSetOneElement() {
    Iterator<List<Integer>> permutations =
        Collections2.permutations(Collections.<Integer>singletonList(1)).iterator();
    assertNextPermutation(newArrayList(1), permutations);
    assertNoMorePermutations(permutations);
  }

  public void testPermutationSetTwoElements() {
    Iterator<List<Integer>> permutations = Collections2.permutations(newArrayList(1, 2)).iterator();
    assertNextPermutation(newArrayList(1, 2), permutations);
    assertNextPermutation(newArrayList(2, 1), permutations);
    assertNoMorePermutations(permutations);
  }

  public void testPermutationSetThreeElements() {
    Iterator<List<Integer>> permutations =
        Collections2.permutations(newArrayList(1, 2, 3)).iterator();
    assertNextPermutation(newArrayList(1, 2, 3), permutations);
    assertNextPermutation(newArrayList(1, 3, 2), permutations);
    assertNextPermutation(newArrayList(3, 1, 2), permutations);

    assertNextPermutation(newArrayList(3, 2, 1), permutations);
    assertNextPermutation(newArrayList(2, 3, 1), permutations);
    assertNextPermutation(newArrayList(2, 1, 3), permutations);
    assertNoMorePermutations(permutations);
  }

  public void testPermutationSetThreeElementsOutOfOrder() {
    Iterator<List<Integer>> permutations =
        Collections2.permutations(newArrayList(3, 2, 1)).iterator();
    assertNextPermutation(newArrayList(3, 2, 1), permutations);
    assertNextPermutation(newArrayList(3, 1, 2), permutations);
    assertNextPermutation(newArrayList(1, 3, 2), permutations);

    assertNextPermutation(newArrayList(1, 2, 3), permutations);
    assertNextPermutation(newArrayList(2, 1, 3), permutations);
    assertNextPermutation(newArrayList(2, 3, 1), permutations);
    assertNoMorePermutations(permutations);
  }

  public void testPermutationSetThreeRepeatedElements() {
    Iterator<List<Integer>> permutations =
        Collections2.permutations(newArrayList(1, 1, 2)).iterator();
    assertNextPermutation(newArrayList(1, 1, 2), permutations);
    assertNextPermutation(newArrayList(1, 2, 1), permutations);
    assertNextPermutation(newArrayList(2, 1, 1), permutations);
    assertNextPermutation(newArrayList(2, 1, 1), permutations);
    assertNextPermutation(newArrayList(1, 2, 1), permutations);
    assertNextPermutation(newArrayList(1, 1, 2), permutations);
    assertNoMorePermutations(permutations);
  }

  public void testPermutationSetFourElements() {
    Iterator<List<Integer>> permutations =
        Collections2.permutations(newArrayList(1, 2, 3, 4)).iterator();
    assertNextPermutation(newArrayList(1, 2, 3, 4), permutations);
    assertNextPermutation(newArrayList(1, 2, 4, 3), permutations);
    assertNextPermutation(newArrayList(1, 4, 2, 3), permutations);
    assertNextPermutation(newArrayList(4, 1, 2, 3), permutations);

    assertNextPermutation(newArrayList(4, 1, 3, 2), permutations);
    assertNextPermutation(newArrayList(1, 4, 3, 2), permutations);
    assertNextPermutation(newArrayList(1, 3, 4, 2), permutations);
    assertNextPermutation(newArrayList(1, 3, 2, 4), permutations);

    assertNextPermutation(newArrayList(3, 1, 2, 4), permutations);
    assertNextPermutation(newArrayList(3, 1, 4, 2), permutations);
    assertNextPermutation(newArrayList(3, 4, 1, 2), permutations);
    assertNextPermutation(newArrayList(4, 3, 1, 2), permutations);

    assertNextPermutation(newArrayList(4, 3, 2, 1), permutations);
    assertNextPermutation(newArrayList(3, 4, 2, 1), permutations);
    assertNextPermutation(newArrayList(3, 2, 4, 1), permutations);
    assertNextPermutation(newArrayList(3, 2, 1, 4), permutations);

    assertNextPermutation(newArrayList(2, 3, 1, 4), permutations);
    assertNextPermutation(newArrayList(2, 3, 4, 1), permutations);
    assertNextPermutation(newArrayList(2, 4, 3, 1), permutations);
    assertNextPermutation(newArrayList(4, 2, 3, 1), permutations);

    assertNextPermutation(newArrayList(4, 2, 1, 3), permutations);
    assertNextPermutation(newArrayList(2, 4, 1, 3), permutations);
    assertNextPermutation(newArrayList(2, 1, 4, 3), permutations);
    assertNextPermutation(newArrayList(2, 1, 3, 4), permutations);
    assertNoMorePermutations(permutations);
  }

  public void testPermutationSetSize() {
    assertPermutationsCount(1, Collections2.permutations(Collections.<Integer>emptyList()));
    assertPermutationsCount(1, Collections2.permutations(newArrayList(1)));
    assertPermutationsCount(2, Collections2.permutations(newArrayList(1, 2)));
    assertPermutationsCount(6, Collections2.permutations(newArrayList(1, 2, 3)));
    assertPermutationsCount(5040, Collections2.permutations(newArrayList(1, 2, 3, 4, 5, 6, 7)));
    assertPermutationsCount(40320, Collections2.permutations(newArrayList(1, 2, 3, 4, 5, 6, 7, 8)));
  }

  public void testPermutationSetSizeOverflow() {
    // 13 elements overflow an int
    assertEquals(
        Integer.MAX_VALUE,
        Collections2.permutations(newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)).size());
    // 21 elements overflow a long
    assertEquals(
        Integer.MAX_VALUE,
        Collections2.orderedPermutations(
                newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20))
            .size());
    assertEquals(
        Integer.MAX_VALUE,
        Collections2.orderedPermutations(
                newArrayList(
                    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21))
            .size());
  }

  public void testPermutationSetContains() {
    List<Integer> list = newArrayList(3, 2, 1);
    Collection<List<Integer>> permutationSet = Collections2.permutations(list);

    assertTrue(permutationSet.contains(newArrayList(1, 2, 3)));
    assertTrue(permutationSet.contains(newArrayList(2, 3, 1)));
    assertFalse(permutationSet.contains(newArrayList(1, 2)));
    assertFalse(permutationSet.contains(newArrayList(1, 1, 2, 3)));
    assertFalse(permutationSet.contains(newArrayList(1, 2, 3, 4)));
    assertFalse(permutationSet.contains(null));
  }

  private <T> void assertNextPermutation(
      List<T> expectedPermutation, Iterator<List<T>> permutations) {
    assertTrue("Expected another permutation, but there was none.", permutations.hasNext());
    assertEquals(expectedPermutation, permutations.next());
  }

  private <T> void assertNoMorePermutations(Iterator<List<T>> permutations) {
    assertFalse("Expected no more permutations, but there was one.", permutations.hasNext());
    try {
      permutations.next();
      fail("Expected NoSuchElementException.");
    } catch (NoSuchElementException expected) {
    }
  }

  private <T> void assertPermutationsCount(int expected, Collection<List<T>> permutationSet) {
    assertEquals(expected, permutationSet.size());
    Iterator<List<T>> permutations = permutationSet.iterator();
    for (int i = 0; i < expected; i++) {
      assertTrue(permutations.hasNext());
      permutations.next();
    }
    assertNoMorePermutations(permutations);
  }

  public void testToStringImplWithNullEntries() throws Exception {
    List<String> list = Lists.newArrayList();
    list.add("foo");
    list.add(null);

    assertEquals(list.toString(), Collections2.toStringImpl(list));
  }
}
