@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.asCallbackQueryUpdate import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.types.CallbackQuery.* import kotlinx.coroutines.flow.toList typealias CallbackQueryMapper = suspend T.() -> T? private suspend fun BehaviourContext.waitCallbackQueries( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, filter: SimpleFilter? = null, mapper: suspend CallbackQuery.() -> O? ): List = expectFlow( initRequest, count, errorFactory ) { val data = it.asCallbackQueryUpdate() ?.data if (data != null && (filter == null || filter(data))) { data.mapper().let(::listOfNotNull) } else { emptyList() } }.toList().toList() private suspend inline fun BehaviourContext.waitCallbacks( count: Int = 1, initRequest: Request<*>? = null, noinline errorFactory: NullableRequestBuilder<*> = { null }, filter: SimpleFilter? = null, noinline mapper: CallbackQueryMapper? = null ) : List = waitCallbackQueries( count, initRequest, errorFactory, filter ?.let { { (it as? T) ?.let { filter(it) } == true } } ) { if (this is T) { if (mapper == null) { this } else { mapper(this) } } else { null } } suspend fun BehaviourContext.waitDataCallbackQuery( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter? = null, mapper: CallbackQueryMapper? = null ) = waitCallbacks(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitGameShortNameCallbackQuery( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter? = null, mapper: CallbackQueryMapper? = null ) = waitCallbacks(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitInlineMessageIdCallbackQuery( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter? = null, mapper: CallbackQueryMapper? = null ) = waitCallbacks(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitInlineMessageIdDataCallbackQuery( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter? = null, mapper: CallbackQueryMapper? = null ) = waitCallbacks(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitInlineMessageIdGameShortNameCallbackQuery( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter? = null, mapper: CallbackQueryMapper? = null ) = waitCallbacks(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitMessageCallbackQuery( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter? = null, mapper: CallbackQueryMapper? = null ) = waitCallbacks(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitMessageDataCallbackQuery( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter? = null, mapper: CallbackQueryMapper? = null ) = waitCallbacks(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitMessageGameShortNameCallbackQuery( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter? = null, mapper: CallbackQueryMapper? = null ) = waitCallbacks(count, initRequest, errorFactory, filter, mapper) suspend fun BehaviourContext.waitUnknownCallbackQuery( initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, count: Int = 1, filter: SimpleFilter? = null, mapper: CallbackQueryMapper? = null ) = waitCallbacks(count, initRequest, errorFactory, filter, mapper)