/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.beam.sdk.values;

import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;

import com.google.common.testing.EqualsTester;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.beam.sdk.Pipeline;
import org.apache.beam.sdk.io.GenerateSequence;
import org.apache.beam.sdk.testing.TestPipeline;
import org.apache.beam.sdk.transforms.Create;
import org.apache.beam.vendor.guava.v20_0.com.google.common.collect.ImmutableList;
import org.joda.time.Duration;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for PCollectionLists. */
@RunWith(JUnit4.class)
public class PCollectionListTest {
  @Test
  public void testEmptyListFailure() {
    try {
      PCollectionList.of(Collections.<PCollection<String>>emptyList());
      fail("should have failed");
    } catch (IllegalArgumentException exn) {
      assertThat(
          exn.toString(),
          containsString(
              "must either have a non-empty list of PCollections, "
                  + "or must first call empty(Pipeline)"));
    }
  }

  @Test
  public void testIterationOrder() {
    Pipeline p = TestPipeline.create();
    PCollection<Long> createOne = p.apply("CreateOne", Create.of(1L, 2L, 3L));
    PCollection<Long> boundedCount = p.apply("CountBounded", GenerateSequence.from(0).to(23));
    PCollection<Long> unboundedCount = p.apply("CountUnbounded", GenerateSequence.from(0));
    PCollection<Long> createTwo = p.apply("CreateTwo", Create.of(-1L, -2L));
    PCollection<Long> maxReadTimeCount =
        p.apply(
            "CountLimited", GenerateSequence.from(0).withMaxReadTime(Duration.standardSeconds(5)));

    ImmutableList<PCollection<Long>> counts =
        ImmutableList.of(boundedCount, maxReadTimeCount, unboundedCount);
    // Build a PCollectionList from a list. This should have the same order as the input list.
    PCollectionList<Long> pcList = PCollectionList.of(counts);
    // Contains is the order-dependent matcher
    assertThat(pcList.getAll(), contains(boundedCount, maxReadTimeCount, unboundedCount));

    // A list that is expanded with builder methods has the added value at the end
    PCollectionList<Long> withOneCreate = pcList.and(createTwo);
    assertThat(
        withOneCreate.getAll(),
        contains(boundedCount, maxReadTimeCount, unboundedCount, createTwo));

    // Lists that are built entirely from the builder return outputs in the order they were added
    PCollectionList<Long> fromEmpty =
        PCollectionList.<Long>empty(p)
            .and(unboundedCount)
            .and(createOne)
            .and(ImmutableList.of(boundedCount, maxReadTimeCount));
    assertThat(
        fromEmpty.getAll(), contains(unboundedCount, createOne, boundedCount, maxReadTimeCount));

    Map<TupleTag<?>, PValue> expansion = fromEmpty.expand();
    // Tag->PValue mappings are stable between expansions. They don't need to be stable across
    // different list instances, though
    assertThat(expansion, equalTo(fromEmpty.expand()));

    List<PCollection<Long>> expectedList =
        ImmutableList.of(unboundedCount, createOne, boundedCount, maxReadTimeCount);
    assertThat(expansion.values(), containsInAnyOrder(expectedList.toArray()));
  }

  @Test
  public void testExpandWithDuplicates() {
    Pipeline p = TestPipeline.create();
    PCollection<Long> createOne = p.apply("CreateOne", Create.of(1L, 2L, 3L));

    PCollectionList<Long> list = PCollectionList.of(createOne).and(createOne).and(createOne);
    assertThat(list.expand().values(), containsInAnyOrder(createOne, createOne, createOne));
  }

  @Test
  public void testEquals() {
    Pipeline p = TestPipeline.create();
    PCollection<String> first = p.apply("Meta", Create.of("foo", "bar"));
    PCollection<String> second = p.apply("Pythonic", Create.of("spam, ham"));
    PCollection<String> third = p.apply("Syntactic", Create.of("eggs", "baz"));

    EqualsTester tester = new EqualsTester();
    //    tester.addEqualityGroup(PCollectionList.empty(p), PCollectionList.empty(p));
    //    tester.addEqualityGroup(PCollectionList.of(first).and(second));
    // Constructors should all produce equivalent
    tester.addEqualityGroup(
        PCollectionList.of(first).and(second).and(third),
        PCollectionList.of(first).and(second).and(third),
        //        PCollectionList.<String>empty(p).and(first).and(second).and(third),
        //        PCollectionList.of(ImmutableList.of(first, second, third)),
        //        PCollectionList.of(first).and(ImmutableList.of(second, third)),
        PCollectionList.of(ImmutableList.of(first, second)).and(third));
    // Order is considered
    tester.addEqualityGroup(PCollectionList.of(first).and(third).and(second));
    tester.addEqualityGroup(PCollectionList.empty(TestPipeline.create()));

    tester.testEquals();
  }
}
