package dev.inmo.tgbotapi.extensions.steps.expectations import dev.inmo.tgbotapi.extensions.steps.Scenario import dev.inmo.tgbotapi.extensions.utils.asContentMessage import dev.inmo.tgbotapi.extensions.utils.asMessageUpdate import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.content.* import dev.inmo.tgbotapi.types.message.content.abstracts.* import dev.inmo.tgbotapi.types.message.content.media.* import dev.inmo.tgbotapi.types.message.payments.InvoiceContent import kotlinx.coroutines.flow.toList typealias ContentMessageToContentMapper = suspend ContentMessage.() -> T? private suspend fun Scenario.waitContentMessage( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, mapper: suspend ContentMessage.() -> O? ): List = expectFlow( initRequest, count, errorFactory ) { it.asMessageUpdate() ?.data ?.asContentMessage() ?.mapper() }.toList().toList() private suspend inline fun Scenario.waitContent( count: Int = 1, initRequest: Request<*>? = null, noinline errorFactory: NullableRequestBuilder<*> = { null }, noinline filter: (suspend (ContentMessage) -> T?)? = null ) : List = waitContentMessage( count, initRequest, errorFactory ) { if (content is T) { val message = (this as ContentMessage) if (filter == null) { message.content } else { filter(message) } } else { null } } suspend fun Scenario.waitContact( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, filter: ContentMessageToContentMapper? = null ) = waitContent(count, initRequest, errorFactory, filter) suspend fun Scenario.waitDice( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, filter: ContentMessageToContentMapper? = null ) = waitContent(count, initRequest, errorFactory, filter) suspend fun Scenario.waitGame( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, filter: ContentMessageToContentMapper? = null ) = waitContent(count, initRequest, errorFactory, filter) suspend fun Scenario.waitLocation( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, filter: ContentMessageToContentMapper? = null ) = waitContent(count, initRequest, errorFactory, filter) suspend fun Scenario.waitPoll( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, filter: ContentMessageToContentMapper? = null ) = waitContent(count, initRequest, errorFactory, filter) suspend fun Scenario.waitText( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, filter: ContentMessageToContentMapper? = null ) = waitContent(count, initRequest, errorFactory, filter) suspend fun Scenario.waitVenue( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, filter: ContentMessageToContentMapper? = null ) = waitContent(count, initRequest, errorFactory, filter) suspend fun Scenario.waitAudioMediaGroup( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, filter: ContentMessageToContentMapper? = null ) = waitContent(count, initRequest, errorFactory, filter) suspend fun Scenario.waitDocumentMediaGroup( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, filter: ContentMessageToContentMapper? = null ) = waitContent(count, initRequest, errorFactory, filter) suspend fun Scenario.waitMedia( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, filter: ContentMessageToContentMapper? = null ) = waitContent(count, initRequest, errorFactory, filter) suspend fun Scenario.waitMediaGroup( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, filter: ContentMessageToContentMapper? = null ) = waitContent(count, initRequest, errorFactory, filter) suspend fun Scenario.waitVisualMediaGroup( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, filter: ContentMessageToContentMapper? = null ) = waitContent(count, initRequest, errorFactory, filter) suspend fun Scenario.waitAnimation( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, filter: ContentMessageToContentMapper? = null ) = waitContent(count, initRequest, errorFactory, filter) suspend fun Scenario.waitAudio( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, filter: ContentMessageToContentMapper? = null ) = waitContent(count, initRequest, errorFactory, filter) suspend fun Scenario.waitDocument( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, filter: ContentMessageToContentMapper? = null ) = waitContent(count, initRequest, errorFactory, filter) suspend fun Scenario.waitPhoto( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, filter: ContentMessageToContentMapper? = null ) = waitContent(count, initRequest, errorFactory, filter) suspend fun Scenario.waitSticker( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, filter: ContentMessageToContentMapper? = null ) = waitContent(count, initRequest, errorFactory, filter) suspend fun Scenario.waitVideo( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, filter: ContentMessageToContentMapper? = null ) = waitContent(count, initRequest, errorFactory, filter) suspend fun Scenario.waitVideoNote( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, filter: ContentMessageToContentMapper? = null ) = waitContent(count, initRequest, errorFactory, filter) suspend fun Scenario.waitVoice( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, filter: ContentMessageToContentMapper? = null ) = waitContent(count, initRequest, errorFactory, filter) suspend fun Scenario.waitInvoice( count: Int = 1, initRequest: Request<*>? = null, errorFactory: NullableRequestBuilder<*> = { null }, filter: ContentMessageToContentMapper? = null ) = waitContent(count, initRequest, errorFactory, filter)