package roomescape.time.implement import io.github.oshai.kotlinlogging.KLogger import io.github.oshai.kotlinlogging.KotlinLogging import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Component import roomescape.reservation.implement.ReservationFinder import roomescape.reservation.infrastructure.persistence.ReservationEntity import roomescape.time.business.domain.TimeWithAvailability import roomescape.theme.implement.ThemeFinder import roomescape.time.exception.TimeErrorCode import roomescape.time.exception.TimeException import roomescape.time.infrastructure.persistence.TimeEntity import roomescape.time.infrastructure.persistence.TimeRepository import java.time.LocalDate private val log: KLogger = KotlinLogging.logger {} @Component class TimeFinder( private val timeRepository: TimeRepository, private val reservationFinder: ReservationFinder, private val themeFinder: ThemeFinder ) { fun findAll(): List { log.debug { "[TimeFinder.findAll] 시작" } return timeRepository.findAll() .also { log.debug { "[TimeFinder.findAll] ${it.size}개 시간 조회 완료" } } } fun findById(id: Long): TimeEntity { log.debug { "[TimeFinder.findById] 조회 시작: timeId=$id" } return timeRepository.findByIdOrNull(id) ?.also { log.debug { "[TimeFinder.findById] 조회 완료: timeId=$id, startAt=${it.startAt}" } } ?: run { log.warn { "[TimeFinder.findById] 조회 실패: timeId=$id" } throw TimeException(TimeErrorCode.TIME_NOT_FOUND) } } fun findAllWithAvailabilityByDateAndThemeId( date: LocalDate, themeId: Long ): List { log.debug { "[TimeFinder.findAllWithAvailabilityByDateAndThemeId] 조회 시작: date:$date, themeId=$themeId" } val theme = themeFinder.findById(themeId) val reservations: List = reservationFinder.findAllByDateAndTheme(date, theme) val allTimes: List = findAll() return allTimes.map { time -> val isReservable: Boolean = reservations.none { reservation -> time.id == reservation.time.id } TimeWithAvailability(time.id!!, time.startAt, date, themeId, isReservable) }.also { log.debug { "[TimeFinder.findAllWithAvailabilityByDateAndThemeId] ${it.size}개 조회 완료: date:$date, themeId=$themeId" } } } }