/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * license agreements; and to You under the Apache License, version 2.0:
 *
 *   https://www.apache.org/licenses/LICENSE-2.0
 *
 * This file is part of the Apache Pekko project, which was derived from Akka.
 */

/*
 * Copyright (C) 2014 - 2016 Softwaremill <https://softwaremill.com>
 * Copyright (C) 2016 - 2020 Lightbend Inc. <https://www.lightbend.com>
 */

package docs.scaladsl

import org.apache.pekko
import org.apache.pekko.kafka.ConsumerSettings
import pekko.kafka.scaladsl.MetadataClient
import pekko.kafka.testkit.scaladsl.TestcontainersKafkaLike
import org.scalatest.TryValues
import org.scalatest.time.{ Seconds, Span }

// #metadata
// #metadataClient
import org.apache.pekko
import pekko.actor.ActorRef
import pekko.kafka.{ KafkaConsumerActor, Metadata }
import pekko.pattern.ask
import pekko.util.Timeout
import org.apache.kafka.common.TopicPartition

import scala.concurrent.Future
import scala.concurrent.duration._

// #metadata
// #metadataClient

class FetchMetadata extends DocsSpecBase with TestcontainersKafkaLike with TryValues {

  override implicit val patienceConfig: PatienceConfig =
    PatienceConfig(timeout = scaled(Span(20, Seconds)), interval = scaled(Span(1, Seconds)))

  "Consumer metadata" should "be available" in {
    val consumerSettings = consumerDefaults.withGroupId(createGroupId())
    val topic = createTopic()
    // #metadata
    val timeout: FiniteDuration = 5.seconds
    val settings = consumerSettings.withMetadataRequestTimeout(timeout)
    implicit val askTimeout: Timeout = Timeout(timeout)

    val consumer: ActorRef = system.actorOf(KafkaConsumerActor.props(settings))

    val topicsFuture: Future[Metadata.Topics] = (consumer ? Metadata.ListTopics).mapTo[Metadata.Topics]

    topicsFuture.map(_.response.foreach { map =>
      println("Found topics:")
      map.foreach {
        case (topic, partitionInfo) =>
          partitionInfo.foreach { info =>
            println(s"  $topic: $info")
          }
      }
    })
    // #metadata
    (topicsFuture.futureValue.response should be).a(Symbol("success"))
    topicsFuture.futureValue.response.get(topic) should not be Symbol("empty")
  }

  "Get topic list" should "return result" in {
    val topic1 = createTopic(1)
    val group1 = createGroupId(1)
    val partition0 = new TopicPartition(topic1, 0)
    val consumerSettings = consumerDefaults.withGroupId(group1)

    awaitProduce(produce(topic1, 1 to 10))

    // #metadataClient
    val metadataClient = MetadataClient.create(consumerSettings, 1.second)

    val beginningOffsets = metadataClient
      .getBeginningOffsets(Set(partition0))
      .futureValue
    // #metadataClient

    beginningOffsets(partition0) shouldBe 0

    // #metadataClient
    metadataClient.close()
    // #metadataClient
  }

  "Get offsets" should "timeout fast" in {
    val consumerSettings: ConsumerSettings[String, String] = consumerDefaults
      .withGroupId(createGroupId())
      .withMetadataRequestTimeout(100.millis)
    val topic = createTopic()
    implicit val timeout: Timeout = Timeout(consumerSettings.metadataRequestTimeout * 2)

    val consumer: ActorRef = system.actorOf(KafkaConsumerActor.props(consumerSettings))

    val nonExistentPartition = 42
    val topicsFuture: Future[Metadata.EndOffsets] =
      (consumer ? Metadata.GetEndOffsets(Set(new TopicPartition(topic, nonExistentPartition))))
        .mapTo[Metadata.EndOffsets]

    val response = topicsFuture.futureValue.response
    (response should be).a(Symbol("failure"))
    response.failed.get shouldBe a[org.apache.kafka.common.errors.TimeoutException]
  }

  it should "return" in {
    val consumerSettings: ConsumerSettings[String, String] = consumerDefaults
      .withGroupId(createGroupId())
      .withMetadataRequestTimeout(5.seconds)
    val topic = createTopic()
    implicit val timeout: Timeout = Timeout(consumerSettings.metadataRequestTimeout * 2)

    val consumer: ActorRef = system.actorOf(KafkaConsumerActor.props(consumerSettings))

    val partition = 0
    val tp = new TopicPartition(topic, partition)
    val topicsFuture: Future[Metadata.EndOffsets] =
      (consumer ? Metadata.GetEndOffsets(Set(tp))).mapTo[Metadata.EndOffsets]

    val response = topicsFuture.futureValue.response
    (response should be).a(Symbol("success"))
    response.get(tp) should be(0L)
  }
}
