import akka.actor.testkit.typed.Effect.ReceiveTimeoutSet
import akka.actor.testkit.typed.javadsl.BehaviorTestKit
import akka.actor.{Actor, ActorSystem, PoisonPill, Props, ReceiveTimeout}
import akka.actor.testkit.typed.scaladsl.ActorTestKit
import akka.actor.typed.{Behavior, Terminated}
import akka.actor.typed.scaladsl.Behaviors
import org.scalatest.BeforeAndAfterAll
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpecLike
import scala.concurrent.duration._
class ReceiveTimeoutSpec extends AnyWordSpecLike with Matchers with BeforeAndAfterAll {
  "Works fine: Classic ReceiveTimeout" should {
    "terminate classic actor - works as expected" in {
      val classic = ActorSystem("classic")
      val classicTestKit = new TestKit(classic)
      class TimeoutActor extends Actor {
        context.setReceiveTimeout(500 millis)
        override def receive: Receive = {
          case ReceiveTimeout => self ! PoisonPill
        }
      }
      val timeoutActor = classic.actorOf(Props(new TimeoutActor()))
      classicTestKit.watch(timeoutActor)
      classicTestKit.expectTerminated(timeoutActor)
    }
  }
  "Questions: ??? Typed ReceiveTimeout ???" should {
    val timeoutBehavior: Behavior[String] = Behaviors.setup[String] { context =>
      context.setReceiveTimeout(500 millis, "terminated")
      Behaviors.receiveMessage {
        case "terminated" => Behaviors.stopped
      }
    }
    "??? terminate typed actor with ActorTestKit - but how ???" in {
      val actorTestKit = ActorTestKit()
      val timeout = actorTestKit.spawn(timeoutBehavior)
      //how to watch that behaviour has terminated???
    }
    "??? terminate typed actor with BehaviorTestKit - but how ???" in {
      val behaviorTestKit = BehaviorTestKit.create(timeoutBehavior)
      //works ...
      behaviorTestKit.expectEffect(ReceiveTimeoutSet(500 millis, "terminated"))
      //...but how to intercept the actual termination (-> Stopped) without sending a message???
    }
  }
}