package link.roadio.riff.player.storage import link.roadio.riff.userstate.model.QueueStateModel internal fun snapshot( q: QueueStateModel, slot: Int, ): PlaybackQueueSnapshot { val cp = q.checkpoint val order by lazy { cp.shuffleOrder.withIndex().associate { it.value to it.index } } val full = q.definition.items val definitionOrdinals by lazy { full.withIndex().associate { it.value.occurrenceId to it.index } } val occurrences = link.roadio.riff.userstate.BoundedReadList(q.execution.items.size) { index -> val it = q.execution.items[index] PlaybackQueueOccurrence( checkNotNull(it.occurrenceId), index, order[it.occurrenceId] ?: index, it.mediaId.media(), ) } return PlaybackQueueSnapshot( checkNotNull(q.execution.id), if (q.id == null ) { PlaybackQueueKind.MANUAL } else { PlaybackQueueKind.PERMANENT_PLAYLIST }, slot, q.id == null, occurrences, PlaybackCheckpoint( cp.occurrenceId, cp.positionUs / 1000, cp.playRequested, cp.repeatEnabled, cp.shuffleEnabled, cp.preferredBindingKey, ), contextKey = queueContext(q), albumContext = q.titleId != null, bookTitleContext = q.kind == 1 && q.titleId != null, bookTitleName = q.name, bookTitleMembers = if (q.kind == 1 ) { link.roadio.riff.userstate .BoundedReadList(full.size) { full[it].mediaId.media() } } else { emptyList() }, bookQueueOrdinals = if (q.kind == 1 ) { link.roadio.riff.userstate.BoundedReadList(q.execution.items.size) { definitionOrdinals[q.execution.items[it].occurrenceId] ?: -1 } } else { emptyList() }, queueId = q.id, audiobook = q.kind == 1, attemptId = cp.attemptId, historyRecorded = cp.historyRecorded, completed = cp.completed, ) } internal fun queueContext(q: QueueStateModel): String? = when { q.id != null -> "${if (q.kind == 1) "bookmarks" else "playlist"}:${q.id}" q.titleId != null -> albumKey(checkNotNull(q.titleId)) else -> null } internal fun playlist(q: QueueStateModel): PermanentPlaylist { val definitionOrdinals = q.definition.items .withIndex() .associate { it.value.occurrenceId to it.index } return PermanentPlaylist( checkNotNull(q.id), q.name.orEmpty(), checkNotNull(q.definition.id), q.definition.items.mapIndexed { i, item, -> PlaylistOccurrence(checkNotNull(item.occurrenceId), i, item.mediaId.media()) }, if (q.kind == 1 ) { PlaylistKind.BOOK } else { PlaylistKind.MUSIC }, q.titleId?.let(::albumKey), q.bookmarks.map { mark -> BookmarkMark( checkNotNull(mark.id), definitionOrdinals[mark.occurrenceId] ?: -1, mark.positionUs, mark.label, ) }, ) }