/*
 * 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 com.google.auto.value.AutoValue;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import javax.annotation.Nullable;
import org.apache.beam.sdk.coders.InstantCoder;
import org.apache.beam.sdk.coders.StructuredCoder;
import org.apache.beam.sdk.transforms.windowing.BoundedWindow;
import org.apache.beam.sdk.transforms.windowing.PaneInfo;
import org.apache.beam.vendor.guava.v20_0.com.google.common.collect.ImmutableList;
import org.joda.time.Instant;

/**
 * An immutable tuple of value, timestamp, window, and pane.
 *
 * @param <T> the type of the value
 */
@AutoValue
public abstract class ValueInSingleWindow<T> {
  /** Returns the value of this {@code ValueInSingleWindow}. */
  @Nullable
  public abstract T getValue();

  /** Returns the timestamp of this {@code ValueInSingleWindow}. */
  public abstract Instant getTimestamp();

  /** Returns the window of this {@code ValueInSingleWindow}. */
  public abstract BoundedWindow getWindow();

  /** Returns the pane of this {@code ValueInSingleWindow} in its window. */
  public abstract PaneInfo getPane();

  public static <T> ValueInSingleWindow<T> of(
      T value, Instant timestamp, BoundedWindow window, PaneInfo paneInfo) {
    return new AutoValue_ValueInSingleWindow<>(value, timestamp, window, paneInfo);
  }

  /** A coder for {@link ValueInSingleWindow}. */
  public static class Coder<T> extends StructuredCoder<ValueInSingleWindow<T>> {
    private final org.apache.beam.sdk.coders.Coder<T> valueCoder;
    private final org.apache.beam.sdk.coders.Coder<BoundedWindow> windowCoder;

    public static <T> Coder<T> of(
        org.apache.beam.sdk.coders.Coder<T> valueCoder,
        org.apache.beam.sdk.coders.Coder<? extends BoundedWindow> windowCoder) {
      return new Coder<>(valueCoder, windowCoder);
    }

    @SuppressWarnings({"unchecked", "rawtypes"})
    Coder(
        org.apache.beam.sdk.coders.Coder<T> valueCoder,
        org.apache.beam.sdk.coders.Coder<? extends BoundedWindow> windowCoder) {
      this.valueCoder = valueCoder;
      this.windowCoder = (org.apache.beam.sdk.coders.Coder) windowCoder;
    }

    @Override
    public void encode(ValueInSingleWindow<T> windowedElem, OutputStream outStream)
        throws IOException {
      encode(windowedElem, outStream, Context.NESTED);
    }

    @Override
    public void encode(ValueInSingleWindow<T> windowedElem, OutputStream outStream, Context context)
        throws IOException {
      InstantCoder.of().encode(windowedElem.getTimestamp(), outStream);
      windowCoder.encode(windowedElem.getWindow(), outStream);
      PaneInfo.PaneInfoCoder.INSTANCE.encode(windowedElem.getPane(), outStream);
      valueCoder.encode(windowedElem.getValue(), outStream, context);
    }

    @Override
    public ValueInSingleWindow<T> decode(InputStream inStream) throws IOException {
      return decode(inStream, Context.NESTED);
    }

    @Override
    public ValueInSingleWindow<T> decode(InputStream inStream, Context context) throws IOException {
      Instant timestamp = InstantCoder.of().decode(inStream);
      BoundedWindow window = windowCoder.decode(inStream);
      PaneInfo pane = PaneInfo.PaneInfoCoder.INSTANCE.decode(inStream);
      T value = valueCoder.decode(inStream, context);
      return new AutoValue_ValueInSingleWindow<>(value, timestamp, window, pane);
    }

    @Override
    public List<? extends org.apache.beam.sdk.coders.Coder<?>> getCoderArguments() {
      // Coder arguments are coders for the type parameters of the coder - i.e. only T.
      return ImmutableList.of(valueCoder);
    }

    @Override
    public List<? extends org.apache.beam.sdk.coders.Coder<?>> getComponents() {
      // Coder components are all inner coders that it uses - i.e. both T and BoundedWindow.
      return ImmutableList.of(valueCoder, windowCoder);
    }

    @Override
    public void verifyDeterministic() throws NonDeterministicException {
      valueCoder.verifyDeterministic();
      windowCoder.verifyDeterministic();
    }
  }
}
