@file:Suppress("unused") package dev.inmo.tgbotapi.extensions.behaviour_builder.expectations import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter import dev.inmo.tgbotapi.extensions.utils.asBaseSentMessageUpdate import dev.inmo.tgbotapi.extensions.utils.asChatEventMessage import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.types.message.ChatEvents.* import dev.inmo.tgbotapi.types.message.ChatEvents.abstracts.* import dev.inmo.tgbotapi.types.message.ChatEvents.voice.* import dev.inmo.tgbotapi.types.message.abstracts.ChatEventMessage import dev.inmo.tgbotapi.types.message.payments.SuccessfulPaymentEvent import kotlinx.coroutines.flow.toList typealias EventMessageToEventMapper = suspend ChatEventMessage.() -> T? private suspend fun BehaviourContext.waitEventMessages( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: suspend ChatEventMessage.() -> O? ): List = expectFlow( initRequest, count, errorFactory ) { val data = it.asBaseSentMessageUpdate() ?.data ?.asChatEventMessage() if (data != null && (filter == null || filter(data))) { data.mapper().let(::listOfNotNull) } else { emptyList() } }.toList().toList() private suspend inline fun BehaviourContext.waitEvents( count: Int = 1, initRequest: Request<*>? = null, noinline errorFactory: NullableRequestBuilder<*> = { null }, noinline filter: SimpleFilter>? = null, noinline mapper: EventMessageToEventMapper? = null ) : List = waitEventMessages( initRequest, errorFactory, count, filter ?.let { { (it.chatEvent as? T) ?.let { filter(it as ChatEventMessage) } == true } } ) { if (chatEvent is T) { @Suppress("UNCHECKED_CAST") val message = (this as ChatEventMessage) if (mapper == null) { message.chatEvent } else { mapper(message) } } else { null } } suspend fun BehaviourContext.waitChannelEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitPrivateEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitChatEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitVoiceChatEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitVoiceChatStartedEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitVoiceChatEndedEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitVoiceChatParticipantsInvitedEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitMessageAutoDeleteTimerChangedEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitCommonGroupEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitCommonEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitGroupEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitSupergroupEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitChannelChatCreatedEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitDeleteChatPhotoEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitGroupChatCreatedEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitLeftChatMemberEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitNewChatPhotoEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitNewChatMembersEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitNewChatTitleEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitPinnedMessageEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitProximityAlertTriggeredEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitSupergroupChatCreatedEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitSuccessfulPaymentEvents( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter>? = null, mapper: EventMessageToEventMapper? = null ) = waitEvents(count, initRequest, errorFactory, filter, mapper)