Newer
Older
bremer / src / main / kotlin / repository / AudioRepository.kt
/*
 * Copyright (c) 2023. yo-saito. All Rights Reserved.
 */

package net.piedpiper.bremer.repository

import net.piedpiper.bremer.dao.*
import net.piedpiper.bremer.entity.AudioEntity
import net.piedpiper.bremer.entity.AudioPlayHistoryEntity
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.stereotype.Repository
import java.time.LocalDateTime

@Repository("bremer.repository.AudioRepository")
class AudioRepository(
    @Qualifier("bremer.dao.AudioDao")
    private val audioDao: AudioDao,
    @Qualifier("bremer.dao.ArtistDao")
    private val artistDao: ArtistDao,
    @Qualifier("bremer.dao.AlbumDao")
    private val albumDao: AlbumDao,
    @Qualifier("bremer.dao.TagDao")
    private val tagDao: TagDao,
    @Qualifier("bremer.dao.AudioPlayHistoryDao")
    private val audioPlayHistoryDao: AudioPlayHistoryDao
) {

    fun findOneBySlug(slug: String): AudioEntity? = audioDao.findOneBySlug(slug)

    fun findAllByIdIn(ids: List<Long>): List<AudioEntity> =
        if (ids.isNotEmpty()) audioDao.findAllByIdIn(ids) else emptyList()

    fun findAllBySlugIn(slugs: List<String>): List<AudioEntity> =
        if (slugs.isNotEmpty()) audioDao.findAllBySlugIn(slugs) else emptyList()

    fun findAllByNameLikeLimit(nameLike: String, limit: Int): List<AudioEntity> =
        audioDao.findAllByNameLikeLimit(nameLike, limit)

    fun findAllByArtistNameLikeLimit(artistNameLike: String, limit: Int): List<AudioEntity> {
        val artists = artistDao.findAllByNameLikeLimit(artistNameLike, limit)
        if (artists.isEmpty()) {
            return emptyList()
        }
        val albums = albumDao.findAllByArtistIdInLimit(artists.map { it.id }.distinct(), limit)
        if (albums.isEmpty()) {
            return emptyList()
        }
        return audioDao.findAllByAlbumIdIn(albums.map { it.id }.distinct())
    }

    fun findAllByAlbumNameLikeLimit(albumNameLike: String, limit: Int): List<AudioEntity> {
        val albums = albumDao.findAllByNameLikeLimit(albumNameLike, limit)
        return if (albums.isNotEmpty()) audioDao
            .findAllByAlbumIdIn(albums.map { it.id }) else emptyList()
    }

    fun findAllByTagLikeLimit(tagNameLike: String, limit: Int): List<AudioEntity> {
        val tags = tagDao.findAllByNameLikeLimit(tagNameLike, limit);
        return if (tags.isNotEmpty()) audioDao
            .findAllByTagIdIn(tags.map { it.id }) else emptyList()
    }

    fun findAllLruLimit(limit: Int): List<AudioEntity> {
        val historyMap = audioPlayHistoryDao.findAllOrderLastPlayedAtDescLimit(limit)
            .associateBy { it.audioId }
        return if (historyMap.isNotEmpty()) audioDao
            .findAllByIdIn(historyMap.keys.map { it })
            .sortedByDescending {
                historyMap[it.id]?.lastPlayedAt ?: LocalDateTime.MIN
            } else emptyList()
    }

    fun saveAudioPlayHistory(entity: AudioPlayHistoryEntity) =
        audioPlayHistoryDao.insertOrUpdateOne(entity)
}