/*
 * 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.runners.direct;

import static org.junit.Assert.assertThat;

import java.io.Serializable;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Optional;
import org.apache.beam.runners.direct.CommittedResult.OutputType;
import org.apache.beam.sdk.coders.VarIntCoder;
import org.apache.beam.sdk.runners.AppliedPTransform;
import org.apache.beam.sdk.testing.TestPipeline;
import org.apache.beam.sdk.transforms.Create;
import org.apache.beam.sdk.transforms.PTransform;
import org.apache.beam.sdk.util.WindowedValue;
import org.apache.beam.sdk.values.PBegin;
import org.apache.beam.sdk.values.PCollection;
import org.apache.beam.sdk.values.PDone;
import org.apache.beam.sdk.values.WindowingStrategy;
import org.apache.beam.vendor.guava.v26_0_jre.com.google.common.collect.ImmutableList;
import org.hamcrest.Matchers;
import org.joda.time.Instant;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link CommittedResult}. */
@RunWith(JUnit4.class)
public class CommittedResultTest implements Serializable {

  @Rule
  public transient TestPipeline p = TestPipeline.create().enableAbandonedNodeEnforcement(false);

  private transient PCollection<Integer> created = p.apply(Create.of(1, 2));
  private transient AppliedPTransform<?, ?, ?> transform =
      AppliedPTransform.<PBegin, PDone, PTransform<PBegin, PDone>>of(
          "foo",
          p.begin().expand(),
          PDone.in(p).expand(),
          new PTransform<PBegin, PDone>() {
            @Override
            public PDone expand(PBegin begin) {
              throw new IllegalArgumentException("Should never be applied");
            }
          },
          p);
  private transient BundleFactory bundleFactory = ImmutableListBundleFactory.create();

  @Test
  public void getTransformExtractsFromResult() {
    CommittedResult<AppliedPTransform<?, ?, ?>> result =
        CommittedResult.create(
            StepTransformResult.withoutHold(transform).build(),
            Optional.empty(),
            Collections.emptyList(),
            EnumSet.noneOf(OutputType.class));

    assertThat(result.getExecutable(), Matchers.<AppliedPTransform<?, ?, ?>>equalTo(transform));
  }

  @Test
  public void getUncommittedElementsEqualInput() {
    CommittedBundle<Integer> bundle =
        bundleFactory
            .createBundle(created)
            .add(WindowedValue.valueInGlobalWindow(2))
            .commit(Instant.now());
    CommittedResult<AppliedPTransform<?, ?, ?>> result =
        CommittedResult.create(
            StepTransformResult.withoutHold(transform).build(),
            Optional.of(bundle),
            Collections.emptyList(),
            EnumSet.noneOf(OutputType.class));

    assertThat(result.getUnprocessedInputs().get(), Matchers.equalTo(bundle));
  }

  @Test
  public void getUncommittedElementsNull() {
    CommittedResult<AppliedPTransform<?, ?, ?>> result =
        CommittedResult.create(
            StepTransformResult.withoutHold(transform).build(),
            Optional.empty(),
            Collections.emptyList(),
            EnumSet.noneOf(OutputType.class));

    assertThat(result.getUnprocessedInputs(), Matchers.equalTo(Optional.empty()));
  }

  @Test
  public void getOutputsEqualInput() {
    List<? extends CommittedBundle<Integer>> outputs =
        ImmutableList.of(
            bundleFactory
                .createBundle(
                    PCollection.createPrimitiveOutputInternal(
                        p,
                        WindowingStrategy.globalDefault(),
                        PCollection.IsBounded.BOUNDED,
                        VarIntCoder.of()))
                .commit(Instant.now()),
            bundleFactory
                .createBundle(
                    PCollection.createPrimitiveOutputInternal(
                        p,
                        WindowingStrategy.globalDefault(),
                        PCollection.IsBounded.UNBOUNDED,
                        VarIntCoder.of()))
                .commit(Instant.now()));
    CommittedResult<AppliedPTransform<?, ?, ?>> result =
        CommittedResult.create(
            StepTransformResult.withoutHold(transform).build(),
            Optional.empty(),
            outputs,
            EnumSet.of(OutputType.BUNDLE, OutputType.PCOLLECTION_VIEW));

    assertThat(result.getOutputs(), Matchers.containsInAnyOrder(outputs.toArray()));
  }
}
