/*
 * 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.transforms.windowing;

import static org.apache.beam.sdk.testing.WindowFnTestUtils.runWindowFn;
import static org.apache.beam.sdk.testing.WindowFnTestUtils.set;
import static org.apache.beam.sdk.transforms.display.DisplayDataMatchers.hasDisplayItem;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.beam.sdk.testing.WindowFnTestUtils;
import org.apache.beam.sdk.transforms.display.DisplayData;
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.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for Sessions WindowFn. */
@RunWith(JUnit4.class)
public class SessionsTest {
  @Rule public ExpectedException thrown = ExpectedException.none();

  @Test
  public void testSimple() throws Exception {
    Map<IntervalWindow, Set<String>> expected = new HashMap<>();
    expected.put(new IntervalWindow(new Instant(0), new Instant(10)), set(0));
    expected.put(new IntervalWindow(new Instant(10), new Instant(20)), set(10));
    expected.put(new IntervalWindow(new Instant(101), new Instant(111)), set(101));
    assertEquals(
        expected,
        runWindowFn(Sessions.withGapDuration(new Duration(10)), Arrays.asList(0L, 10L, 101L)));
  }

  @Test
  public void testConsecutive() throws Exception {
    Map<IntervalWindow, Set<String>> expected = new HashMap<>();
    expected.put(new IntervalWindow(new Instant(1), new Instant(19)), set(1, 2, 5, 9));
    expected.put(new IntervalWindow(new Instant(100), new Instant(111)), set(100, 101));
    assertEquals(
        expected,
        runWindowFn(
            Sessions.withGapDuration(new Duration(10)), Arrays.asList(1L, 2L, 5L, 9L, 100L, 101L)));
  }

  @Test
  public void testMerging() throws Exception {
    Map<IntervalWindow, Set<String>> expected = new HashMap<>();
    expected.put(new IntervalWindow(new Instant(1), new Instant(40)), set(1, 10, 15, 22, 30));
    expected.put(new IntervalWindow(new Instant(95), new Instant(111)), set(95, 100, 101));
    assertEquals(
        expected,
        runWindowFn(
            Sessions.withGapDuration(new Duration(10)),
            Arrays.asList(1L, 15L, 30L, 100L, 101L, 95L, 22L, 10L)));
  }

  @Test
  public void testTimeUnit() throws Exception {
    Map<IntervalWindow, Set<String>> expected = new HashMap<>();
    expected.put(new IntervalWindow(new Instant(1), new Instant(2000)), set(1, 2, 1000));
    expected.put(new IntervalWindow(new Instant(5000), new Instant(6001)), set(5000, 5001));
    expected.put(new IntervalWindow(new Instant(10000), new Instant(11000)), set(10000));
    assertEquals(
        expected,
        runWindowFn(
            Sessions.withGapDuration(Duration.standardSeconds(1)),
            Arrays.asList(1L, 2L, 1000L, 5000L, 5001L, 10000L)));
  }

  @Test
  public void testEquality() {
    assertTrue(
        Sessions.withGapDuration(new Duration(10))
            .isCompatible(Sessions.withGapDuration(new Duration(10))));
    assertTrue(
        Sessions.withGapDuration(new Duration(10))
            .isCompatible(Sessions.withGapDuration(new Duration(20))));
  }

  @Test
  public void testVerifyCompatibility() throws IncompatibleWindowException {
    Sessions.withGapDuration(new Duration(10))
        .verifyCompatibility(Sessions.withGapDuration(new Duration(10)));

    thrown.expect(IncompatibleWindowException.class);
    Sessions.withGapDuration(new Duration(10))
        .verifyCompatibility(FixedWindows.of(new Duration(10)));
  }

  /** Validates that the output timestamp for aggregate data falls within the acceptable range. */
  @Test
  public void testValidOutputTimes() throws Exception {
    for (long timestamp : Arrays.asList(200, 800, 700)) {
      WindowFnTestUtils.validateGetOutputTimestamp(
          Sessions.withGapDuration(Duration.millis(500)), timestamp);
    }
  }

  /**
   * Test to confirm that {@link Sessions} with the default {@link TimestampCombiner} holds up the
   * watermark potentially indefinitely.
   */
  @Test
  public void testInvalidOutputAtEarliest() throws Exception {
    try {
      WindowFnTestUtils.validateGetOutputTimestamps(
          Sessions.withGapDuration(Duration.millis(10)),
          TimestampCombiner.EARLIEST,
          ImmutableList.of(
              (List<Long>) ImmutableList.of(1L, 3L),
              (List<Long>) ImmutableList.of(0L, 5L, 10L, 15L, 20L)));
    } catch (AssertionError exc) {
      assertThat(
          exc.getMessage(),
          // These are the non-volatile pieces of the error message that a timestamp
          // was not greater than what it should be.
          allOf(containsString("a value greater than"), containsString("was less than")));
    }
  }

  /**
   * When a user explicitly requests per-key aggregate values have their derived timestamp to be the
   * end of the window (instead of the earliest possible), the session here should not hold each
   * other up, even though they overlap.
   */
  @Test
  public void testValidOutputAtEndTimes() throws Exception {
    WindowFnTestUtils.validateGetOutputTimestamps(
        Sessions.withGapDuration(Duration.millis(10)),
        TimestampCombiner.END_OF_WINDOW,
        ImmutableList.of(
            (List<Long>) ImmutableList.of(1L, 3L),
            (List<Long>) ImmutableList.of(0L, 5L, 10L, 15L, 20L)));
  }

  @Test
  public void testDisplayData() {
    Duration gapDuration = Duration.standardMinutes(234);
    Sessions session = Sessions.withGapDuration(gapDuration);
    assertThat(DisplayData.from(session), hasDisplayItem("gapDuration", gapDuration));
  }
}
