/*
 * 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.io.gcp.pubsub;

import static org.junit.Assert.assertEquals;

import java.util.Map;
import org.apache.beam.sdk.io.gcp.pubsub.PubsubClient.ProjectPath;
import org.apache.beam.sdk.io.gcp.pubsub.PubsubClient.SubscriptionPath;
import org.apache.beam.sdk.io.gcp.pubsub.PubsubClient.TopicPath;
import org.apache.beam.vendor.guava.v20_0.com.google.common.collect.ImmutableMap;
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 helper classes and methods in PubsubClient. */
@RunWith(JUnit4.class)
public class PubsubClientTest {
  @Rule public ExpectedException thrown = ExpectedException.none();

  //
  // Timestamp handling
  //

  private long parse(String timestamp) {
    Map<String, String> map = ImmutableMap.of("myAttribute", timestamp);
    return PubsubClient.extractTimestamp("myAttribute", null, map);
  }

  private void roundTripRfc339(String timestamp) {
    assertEquals(Instant.parse(timestamp).getMillis(), parse(timestamp));
  }

  private void truncatedRfc339(String timestamp, String truncatedTimestmap) {
    assertEquals(Instant.parse(truncatedTimestmap).getMillis(), parse(timestamp));
  }

  @Test
  public void noTimestampAttributeReturnsPubsubPublish() {
    final long time = 987654321L;
    long timestamp = PubsubClient.extractTimestamp(null, String.valueOf(time), null);
    assertEquals(time, timestamp);
  }

  @Test
  public void noTimestampAttributeAndInvalidPubsubPublishThrowsError() {
    thrown.expect(NumberFormatException.class);
    PubsubClient.extractTimestamp(null, "not-a-date", null);
  }

  @Test
  public void timestampAttributeWithNullAttributesThrowsError() {
    thrown.expect(RuntimeException.class);
    thrown.expectMessage("PubSub message is missing a value for timestamp attribute myAttribute");
    PubsubClient.extractTimestamp("myAttribute", null, null);
  }

  @Test
  public void timestampAttributeSetWithMissingAttributeThrowsError() {
    thrown.expect(RuntimeException.class);
    thrown.expectMessage("PubSub message is missing a value for timestamp attribute myAttribute");
    Map<String, String> map = ImmutableMap.of("otherLabel", "whatever");
    PubsubClient.extractTimestamp("myAttribute", null, map);
  }

  @Test
  public void timestampAttributeParsesMillisecondsSinceEpoch() {
    long time = 1446162101123L;
    Map<String, String> map = ImmutableMap.of("myAttribute", String.valueOf(time));
    long timestamp = PubsubClient.extractTimestamp("myAttribute", null, map);
    assertEquals(time, timestamp);
  }

  @Test
  public void timestampAttributeParsesRfc3339Seconds() {
    roundTripRfc339("2015-10-29T23:41:41Z");
  }

  @Test
  public void timestampAttributeParsesRfc3339Tenths() {
    roundTripRfc339("2015-10-29T23:41:41.1Z");
  }

  @Test
  public void timestampAttributeParsesRfc3339Hundredths() {
    roundTripRfc339("2015-10-29T23:41:41.12Z");
  }

  @Test
  public void timestampAttributeParsesRfc3339Millis() {
    roundTripRfc339("2015-10-29T23:41:41.123Z");
  }

  @Test
  public void timestampAttributeParsesRfc3339Micros() {
    // Note: micros part 456/1000 is dropped.
    truncatedRfc339("2015-10-29T23:41:41.123456Z", "2015-10-29T23:41:41.123Z");
  }

  @Test
  public void timestampAttributeParsesRfc3339MicrosRounding() {
    // Note: micros part 999/1000 is dropped, not rounded up.
    truncatedRfc339("2015-10-29T23:41:41.123999Z", "2015-10-29T23:41:41.123Z");
  }

  @Test
  public void timestampAttributeWithInvalidFormatThrowsError() {
    thrown.expect(NumberFormatException.class);
    parse("not-a-timestamp");
  }

  @Test
  public void timestampAttributeWithInvalidFormat2ThrowsError() {
    thrown.expect(NumberFormatException.class);
    parse("null");
  }

  @Test
  public void timestampAttributeWithInvalidFormat3ThrowsError() {
    thrown.expect(NumberFormatException.class);
    parse("2015-10");
  }

  @Test
  public void timestampAttributeParsesRfc3339WithSmallYear() {
    // Google and JodaTime agree on dates after 1582-10-15, when the Gregorian Calendar was adopted
    // This is therefore a "small year" until this difference is reconciled.
    roundTripRfc339("1582-10-15T01:23:45.123Z");
  }

  @Test
  public void timestampAttributeParsesRfc3339WithLargeYear() {
    // Year 9999 in range.
    roundTripRfc339("9999-10-29T23:41:41.123999Z");
  }

  @Test
  public void timestampAttributeRfc3339WithTooLargeYearThrowsError() {
    thrown.expect(NumberFormatException.class);
    // Year 10000 out of range.
    parse("10000-10-29T23:41:41.123999Z");
  }

  //
  // Paths
  //

  @Test
  public void projectPathFromIdWellFormed() {
    ProjectPath path = PubsubClient.projectPathFromId("test");
    assertEquals("projects/test", path.getPath());
  }

  @Test
  public void subscriptionPathFromNameWellFormed() {
    SubscriptionPath path = PubsubClient.subscriptionPathFromName("test", "something");
    assertEquals("projects/test/subscriptions/something", path.getPath());
    assertEquals("/subscriptions/test/something", path.getV1Beta1Path());
  }

  @Test
  public void topicPathFromNameWellFormed() {
    TopicPath path = PubsubClient.topicPathFromName("test", "something");
    assertEquals("projects/test/topics/something", path.getPath());
    assertEquals("/topics/test/something", path.getV1Beta1Path());
  }
}
