package service import ( "context" "errors" "fmt" "gitea.dwysokinski.me/twhelp/dcbot/internal/domain" "gitea.dwysokinski.me/twhelp/dcbot/internal/twhelp" ) const ( maxGroupsPerServer = 10 ) //counterfeiter:generate -o internal/mock/group_repository.gen.go . GroupRepository type GroupRepository interface { Create(ctx context.Context, params domain.CreateGroupParams) (domain.Group, error) UpdateByID(ctx context.Context, id string, params domain.UpdateGroupParams) (domain.Group, error) List(ctx context.Context, params domain.ListGroupsParams) ([]domain.Group, error) } type Group struct { repo GroupRepository client TWHelpClient } func NewGroup(repo GroupRepository, client TWHelpClient) *Group { return &Group{repo: repo, client: client} } func (g *Group) Create(ctx context.Context, params domain.CreateGroupParams) (domain.Group, error) { groups, err := g.repo.List(ctx, domain.ListGroupsParams{ ServerIDs: []string{params.ServerID()}, }) if err != nil { return domain.Group{}, fmt.Errorf("GroupRepository.List: %w", err) } if len(groups) >= maxGroupsPerServer { return domain.Group{}, domain.GroupLimitReachedError{ Current: len(groups), Limit: maxGroupsPerServer, } } server, err := g.client.GetServer(ctx, params.VersionCode(), params.ServerKey()) if err != nil { var apiErr twhelp.APIError if !errors.As(err, &apiErr) { return domain.Group{}, fmt.Errorf("TWHelpClient.GetServer: %w", err) } return domain.Group{}, domain.ServerDoesNotExistError{ VersionCode: params.VersionCode(), Key: params.ServerKey(), } } if !server.Open { return domain.Group{}, domain.ServerIsClosedError{ VersionCode: params.VersionCode(), Key: params.ServerKey(), } } group, err := g.repo.Create(ctx, params) if err != nil { return domain.Group{}, fmt.Errorf("GroupRepository.Create: %w", err) } return group, nil } func (g *Group) SetTWServer(ctx context.Context, id, versionCode, serverKey string) (domain.Group, error) { if err := g.checkTWServer(ctx, versionCode, serverKey); err != nil { return domain.Group{}, err } group, err := g.repo.UpdateByID(ctx, id, domain.UpdateGroupParams{ VersionCode: domain.NullString{ String: versionCode, Valid: true, }, ServerKey: domain.NullString{ String: serverKey, Valid: true, }, }) if err != nil { return domain.Group{}, fmt.Errorf("GroupRepository.UpdateByID: %w", err) } return group, nil } func (g *Group) SetChannelGains(ctx context.Context, id, channel string) (domain.Group, error) { group, err := g.repo.UpdateByID(ctx, id, domain.UpdateGroupParams{ ChannelGains: domain.NullString{ String: channel, Valid: true, }, }) if err != nil { return domain.Group{}, fmt.Errorf("GroupRepository.UpdateByID: %w", err) } return group, nil } func (g *Group) SetChannelLosses(ctx context.Context, id, channel string) (domain.Group, error) { group, err := g.repo.UpdateByID(ctx, id, domain.UpdateGroupParams{ ChannelLosses: domain.NullString{ String: channel, Valid: true, }, }) if err != nil { return domain.Group{}, fmt.Errorf("GroupRepository.UpdateByID: %w", err) } return group, nil } func (g *Group) List(ctx context.Context, params domain.ListGroupsParams) ([]domain.Group, error) { groups, err := g.repo.List(ctx, params) if err != nil { return nil, fmt.Errorf("GroupRepository.List: %w", err) } return groups, nil } func (g *Group) checkTWServer(ctx context.Context, versionCode, serverKey string) error { server, err := g.client.GetServer(ctx, versionCode, serverKey) if err != nil { var apiErr twhelp.APIError if !errors.As(err, &apiErr) { return fmt.Errorf("TWHelpClient.GetServer: %w", err) } return domain.ServerDoesNotExistError{ VersionCode: versionCode, Key: serverKey, } } if !server.Open { return domain.ServerIsClosedError{ VersionCode: versionCode, Key: serverKey, } } return nil }