/*
 * 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.core.construction;

import static org.apache.beam.runners.core.construction.PTransformTranslation.TEST_STREAM_TRANSFORM_URN;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;

import org.apache.beam.model.pipeline.v1.RunnerApi;
import org.apache.beam.model.pipeline.v1.RunnerApi.TestStreamPayload;
import org.apache.beam.sdk.coders.StringUtf8Coder;
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.testing.TestStream;
import org.apache.beam.sdk.values.PBegin;
import org.apache.beam.sdk.values.PCollection;
import org.apache.beam.sdk.values.TimestampedValue;
import org.apache.beam.vendor.guava.v20_0.com.google.common.collect.ImmutableList;
import org.joda.time.Duration;
import org.joda.time.Instant;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

/** Tests for {@link TestStreamTranslation}. */
@RunWith(Parameterized.class)
public class TestStreamTranslationTest {
  @Parameters(name = "{index}: {0}")
  public static Iterable<TestStream<?>> data() {
    return ImmutableList.of(
        TestStream.create(VarIntCoder.of()).advanceWatermarkToInfinity(),
        TestStream.create(VarIntCoder.of())
            .advanceWatermarkTo(new Instant(42))
            .advanceWatermarkToInfinity(),
        TestStream.create(VarIntCoder.of())
            .addElements(TimestampedValue.of(3, new Instant(17)))
            .advanceWatermarkToInfinity(),
        TestStream.create(StringUtf8Coder.of())
            .advanceProcessingTime(Duration.millis(82))
            .advanceWatermarkToInfinity());
  }

  @Parameter(0)
  public TestStream<String> testStream;

  public static TestPipeline p = TestPipeline.create().enableAbandonedNodeEnforcement(false);

  @Test
  public void testEncodedProto() throws Exception {
    SdkComponents components = SdkComponents.create();
    components.registerEnvironment(Environments.createDockerEnvironment("java"));
    RunnerApi.TestStreamPayload payload =
        TestStreamTranslation.payloadForTestStream(testStream, components);

    verifyTestStreamEncoding(
        testStream, payload, RehydratedComponents.forComponents(components.toComponents()));
  }

  @Test
  public void testRegistrarEncodedProto() throws Exception {
    PCollection<String> output = p.apply(testStream);

    AppliedPTransform<PBegin, PCollection<String>, TestStream<String>> appliedTestStream =
        AppliedPTransform.of("fakeName", PBegin.in(p).expand(), output.expand(), testStream, p);

    SdkComponents components = SdkComponents.create();
    components.registerEnvironment(Environments.createDockerEnvironment("java"));
    RunnerApi.FunctionSpec spec =
        PTransformTranslation.toProto(appliedTestStream, components).getSpec();

    assertThat(spec.getUrn(), equalTo(TEST_STREAM_TRANSFORM_URN));

    RunnerApi.TestStreamPayload payload = TestStreamPayload.parseFrom(spec.getPayload());

    verifyTestStreamEncoding(
        testStream, payload, RehydratedComponents.forComponents(components.toComponents()));
  }

  private static <T> void verifyTestStreamEncoding(
      TestStream<T> testStream,
      RunnerApi.TestStreamPayload payload,
      RehydratedComponents protoComponents)
      throws Exception {

    // This reverse direction is only valid for Java-based coders
    assertThat(protoComponents.getCoder(payload.getCoderId()), equalTo(testStream.getValueCoder()));

    assertThat(payload.getEventsList().size(), equalTo(testStream.getEvents().size()));

    for (int i = 0; i < payload.getEventsList().size(); ++i) {
      assertThat(
          TestStreamTranslation.eventFromProto(payload.getEvents(i), testStream.getValueCoder()),
          equalTo(testStream.getEvents().get(i)));
    }
  }
}
