/*
* Copyright (c) 2023. yo-saito. All Rights Reserved.
*/
package net.piedpiper.bremer.service.app
import net.piedpiper.bremer.entity.PlaylistAudioEntity
import net.piedpiper.bremer.entity.PlaylistEntity
import net.piedpiper.bremer.exception.BadRequestException
import net.piedpiper.bremer.exception.NotFoundException
import net.piedpiper.bremer.model.PlaylistAudioResponse
import net.piedpiper.bremer.model.PlaylistListResponse
import net.piedpiper.bremer.model.PlaylistRequest
import net.piedpiper.bremer.service.domain.AudioDomainService
import net.piedpiper.bremer.service.domain.PlaylistDomainService
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.util.UUID
@Service("bremer.service.PlaylistAppService")
class PlaylistAppService(
@Qualifier("bremer.service.PlaylistDomainService")
private val playlistDomainService: PlaylistDomainService,
@Qualifier("bremer.service.AudioDomainService")
private val audioDomainService: AudioDomainService
) {
@Transactional
fun getAllPlaylists(): PlaylistListResponse =
PlaylistListResponse(playlistDomainService.findAll())
@Transactional
fun getPlaylist(slug: String): PlaylistAudioResponse =
convertToPlaylistAudioResponse(
playlistDomainService.findOneBySlug(slug) ?: throw NotFoundException()
)
@Transactional
fun createPlaylist(request: PlaylistRequest): PlaylistAudioResponse =
playlistDomainService.insertOne(
convertToPlaylistEntity(request)
).let { entity ->
val audioList = entity?.playlistAudio?.mapNotNull { it.audioId }
?.let {
audioDomainService.findAllByOrderedIds(it)
} ?: emptyList()
PlaylistAudioResponse(
playlistEntity = entity,
audioEntityList = audioList
)
}
@Transactional
fun updatePlaylist(slug: String, request: PlaylistRequest): PlaylistAudioResponse =
playlistDomainService.findOneBySlug(slug)
?.let { playlist ->
playlist.name = request.name
val audioList = audioDomainService.findAllByOrderedSlugs(request.audioSlugs)
if (request.audioSlugs.size != audioList.size) {
throw BadRequestException()
}
val playlistSize = playlist.playlistAudio?.size ?: 0
playlist.playlistAudio = audioList.mapIndexed { idx, audio ->
PlaylistAudioEntity(
id = if (idx >= playlistSize) 0L else playlist?.playlistAudio!![idx].id,
playlistId = playlist.id,
sequence = idx,
audioId = audio.id
)
}
playlistDomainService.updateOne(
playlist
).let {
PlaylistAudioResponse(
playlistEntity = playlist,
audioEntityList = audioList
)
}
} ?: throw NotFoundException()
private fun convertToPlaylistEntity(
request: PlaylistRequest,
id: Long = 0L,
slug: String? = null
): PlaylistEntity =
request.audioSlugs?.let {
audioDomainService.findAllByOrderedSlugs(it)
}?.associate { it.slug to it.id }
.let { audioIdMap ->
PlaylistEntity(
id = id,
slug = slug ?: UUID.randomUUID().toString(),
name = request.name,
playlistAudio = request.audioSlugs?.mapIndexed { idx, slug ->
PlaylistAudioEntity(
audioId = audioIdMap?.get(slug) ?: 0L,
sequence = idx
)
} ?: emptyList()
)
}
private fun convertToPlaylistAudioResponse(entity: PlaylistEntity): PlaylistAudioResponse {
val audioList = entity?.playlistAudio?.mapNotNull { it.audioId }
?.let {
audioDomainService.findAllByOrderedIds(it)
} ?: emptyList()
return PlaylistAudioResponse(
playlistEntity = entity,
audioEntityList = audioList
)
}
}