/*
 * 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) 2018-2022 Lightbend Inc. <https://www.lightbend.com>
 */

package org.apache.pekko.stream.testkit

import org.apache.pekko
import pekko.actor.Actor
import pekko.actor.ActorRef
import pekko.actor.ActorRefWithCell
import pekko.actor.ActorSystem
import pekko.dispatch.MailboxType
import pekko.dispatch.MessageQueue
import pekko.dispatch.ProducesMessageQueue
import pekko.dispatch.UnboundedMailbox
import pekko.stream.impl.MaterializerGuardian

import com.typesafe.config.Config

/**
 * INTERNAL API
 * This mailbox is only used in tests to verify that stream actors are using
 * the dispatcher defined in ActorMaterializerSettings.
 */
private[pekko] final case class StreamTestDefaultMailbox()
    extends MailboxType
    with ProducesMessageQueue[UnboundedMailbox.MessageQueue] {

  def this(settings: ActorSystem.Settings, config: Config) = this()

  final override def create(owner: Option[ActorRef], system: Option[ActorSystem]): MessageQueue = {
    owner match {
      case Some(r: ActorRefWithCell) =>
        val actorClass = r.underlying.props.actorClass()
        assert(
          actorClass != classOf[Actor],
          s"Don't use anonymous actor classes, actor class for $r was [${actorClass.getName}]")
        // StreamTcpManager is allowed to use another dispatcher
        assert(
          actorClass == classOf[MaterializerGuardian] || !actorClass.getName.startsWith("org.apache.pekko.stream."),
          s"$r with actor class [${actorClass.getName}] must not run on default dispatcher in tests. " +
          "Did you forget to define `props.withDispatcher` when creating the actor? " +
          "Or did you forget to configure the `org.apache.pekko.stream.materializer` setting accordingly or force the " +
          """dispatcher using `ActorMaterializerSettings(sys).withDispatcher("org.apache.pekko.test.stream-dispatcher")` in the test?""")
      case _ =>
    }
    new UnboundedMailbox.MessageQueue
  }
}
