75 lines
1.9 KiB
Go
75 lines
1.9 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"regexp"
|
|
"time"
|
|
|
|
"watch-party-backend/internal/repo"
|
|
)
|
|
|
|
var (
|
|
ErrInvalidTime = errors.New("invalid start_time (expected HH:MM:SS)")
|
|
ErrEmptyIDs = errors.New("ids must not be empty")
|
|
)
|
|
|
|
type EpisodeService interface {
|
|
GetCurrent(ctx context.Context) (repo.Episode, error)
|
|
SetCurrent(ctx context.Context, id int64, start string) (repo.Episode, error)
|
|
MoveToArchive(ctx context.Context, ids []int64) (repo.MoveResult, error)
|
|
ListAll(ctx context.Context) ([]repo.Episode, error)
|
|
}
|
|
|
|
type episodeService struct {
|
|
repo repo.EpisodeRepository
|
|
}
|
|
|
|
func NewEpisodeService(r repo.EpisodeRepository) EpisodeService {
|
|
return &episodeService{repo: r}
|
|
}
|
|
|
|
func (s *episodeService) ListAll(ctx context.Context) ([]repo.Episode, error) {
|
|
c, cancel := context.WithTimeout(ctx, 5*time.Second)
|
|
defer cancel()
|
|
return s.repo.ListAll(c)
|
|
}
|
|
|
|
func (s *episodeService) GetCurrent(ctx context.Context) (repo.Episode, error) {
|
|
c, cancel := context.WithTimeout(ctx, 3*time.Second)
|
|
defer cancel()
|
|
return s.repo.GetCurrent(c)
|
|
}
|
|
|
|
var hhmmss = regexp.MustCompile(`^(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d$`)
|
|
|
|
func (s *episodeService) SetCurrent(ctx context.Context, id int64, start string) (repo.Episode, error) {
|
|
if !hhmmss.MatchString(start) {
|
|
return repo.Episode{}, ErrInvalidTime
|
|
}
|
|
c, cancel := context.WithTimeout(ctx, 5*time.Second)
|
|
defer cancel()
|
|
if err := s.repo.SetCurrent(c, id, start); err != nil {
|
|
return repo.Episode{}, err
|
|
}
|
|
return s.repo.GetCurrent(c)
|
|
}
|
|
|
|
func (s *episodeService) MoveToArchive(ctx context.Context, ids []int64) (repo.MoveResult, error) {
|
|
uniq := make([]int64, 0, len(ids))
|
|
seen := make(map[int64]struct{}, len(ids))
|
|
for _, id := range ids {
|
|
if _, ok := seen[id]; !ok {
|
|
seen[id] = struct{}{}
|
|
uniq = append(uniq, id)
|
|
}
|
|
}
|
|
if len(uniq) == 0 {
|
|
return repo.MoveResult{}, ErrEmptyIDs
|
|
}
|
|
|
|
c, cancel := context.WithTimeout(ctx, 10*time.Second)
|
|
defer cancel()
|
|
return s.repo.MoveToArchive(c, uniq)
|
|
}
|