package app import ( "context" "errors" "fmt" "time" "gitea.dwysokinski.me/twhelp/corev3/internal/domain" ) type SnapshotService struct { versionSvc *VersionService serverSvc *ServerService tribeSnapshotPublisher SnapshotPublisher playerSnapshotPublisher SnapshotPublisher } func NewSnapshotService( versionSvc *VersionService, serverSvc *ServerService, tribeSnapshotPublisher SnapshotPublisher, playerSnapshotPublisher SnapshotPublisher, ) *SnapshotService { return &SnapshotService{ versionSvc: versionSvc, serverSvc: serverSvc, tribeSnapshotPublisher: tribeSnapshotPublisher, playerSnapshotPublisher: playerSnapshotPublisher, } } func (svc *SnapshotService) Create(ctx context.Context) error { listVersionsRes, err := svc.versionSvc.List(ctx, domain.NewListVersionsParams()) if err != nil { return err } versions := listVersionsRes.Versions() for _, v := range versions { loc, loopErr := time.LoadLocation(v.Timezone()) if loopErr != nil { return fmt.Errorf("%s: %w", v.Code(), err) } year, month, day := time.Now().In(loc).Date() snapshotsCreatedAtLT := time.Date(year, month, day, 0, 0, 0, 0, loc) date := time.Date(year, month, day, 0, 0, 0, 0, time.UTC) loopErr = errors.Join( svc.publishTribe(ctx, v, snapshotsCreatedAtLT, date), svc.publishPlayer(ctx, v, snapshotsCreatedAtLT, date), ) if loopErr != nil { return loopErr } } return nil } func (svc *SnapshotService) publishTribe( ctx context.Context, v domain.Version, snapshotsCreatedAtLT time.Time, date time.Time, ) error { params := domain.NewListServersParams() if err := params.SetVersionCodes([]string{v.Code()}); err != nil { return err } if err := params.SetOpen(domain.NullBool{ V: true, Valid: true, }); err != nil { return err } if err := params.SetTribeSnapshotsCreatedAtLT(domain.NullTime{ V: snapshotsCreatedAtLT, Valid: true, }); err != nil { return err } servers, err := svc.serverSvc.ListAll(ctx, params) if err != nil { return err } payloads, err := svc.toPayload(v, servers, date) if err != nil { return err } return svc.tribeSnapshotPublisher.CmdCreate(ctx, payloads...) } func (svc *SnapshotService) publishPlayer( ctx context.Context, v domain.Version, snapshotsCreatedAtLT time.Time, date time.Time, ) error { params := domain.NewListServersParams() if err := params.SetVersionCodes([]string{v.Code()}); err != nil { return err } if err := params.SetOpen(domain.NullBool{ V: true, Valid: true, }); err != nil { return err } if err := params.SetPlayerSnapshotsCreatedAtLT(domain.NullTime{ V: snapshotsCreatedAtLT, Valid: true, }); err != nil { return err } servers, err := svc.serverSvc.ListAll(ctx, params) if err != nil { return err } payloads, err := svc.toPayload(v, servers, date) if err != nil { return err } return svc.playerSnapshotPublisher.CmdCreate(ctx, payloads...) } func (svc *SnapshotService) toPayload( v domain.Version, servers domain.Servers, date time.Time, ) ([]domain.CreateSnapshotsCmdPayload, error) { payloads := make([]domain.CreateSnapshotsCmdPayload, 0, len(servers)) for _, s := range servers { p, err := domain.NewCreateSnapshotsCmdPayload(s.Key(), v.Code(), v.Timezone(), date) if err != nil { return nil, fmt.Errorf("%s: couldn't construct domain.CreateSnapshotsCmdPayload: %w", s.Key(), err) } payloads = append(payloads, p) } return payloads, nil }