package adapter import ( "context" "errors" "slices" "strings" "time" "gitea.dwysokinski.me/twhelp/dcbot/internal/domain" "gitea.dwysokinski.me/twhelp/dcbot/internal/twhelp" ) type TWHelpHTTP struct { client *twhelp.ClientWithResponses } func NewTWHelpHTTP(client *twhelp.ClientWithResponses) *TWHelpHTTP { return &TWHelpHTTP{client: client} } func (t *TWHelpHTTP) ListVersions(ctx context.Context) ([]domain.TWVersion, error) { resp, err := t.client.ListVersionsWithResponse(ctx, nil) if err != nil { return nil, err } if resp.JSONDefault != nil { return nil, t.convertErrors(resp.JSONDefault.Errors) } res := make([]domain.TWVersion, 0, len(resp.JSON200.Data)) for _, v := range resp.JSON200.Data { res = append(res, t.convertVersionToDomain(v)) } return res, nil } func (t *TWHelpHTTP) ListOpenServers(ctx context.Context, versionCode string, limit int) ([]domain.TWServer, error) { open := true return t.listServers(ctx, versionCode, &twhelp.ListServersParams{ Limit: &limit, Open: &open, }) } func (t *TWHelpHTTP) ListClosedServers(ctx context.Context, versionCode string, limit int) ([]domain.TWServer, error) { open := false return t.listServers(ctx, versionCode, &twhelp.ListServersParams{ Limit: &limit, Open: &open, }) } func (t *TWHelpHTTP) listServers(ctx context.Context, versionCode string, params *twhelp.ListServersParams) ([]domain.TWServer, error) { resp, err := t.client.ListServersWithResponse(ctx, versionCode, params) if err != nil { return nil, err } if resp.JSONDefault != nil { return nil, t.convertErrors(resp.JSONDefault.Errors) } res := make([]domain.TWServer, 0, len(resp.JSON200.Data)) for _, s := range resp.JSON200.Data { res = append(res, t.convertServerToDomain(s)) } return res, nil } func (t *TWHelpHTTP) GetOpenServer(ctx context.Context, versionCode, serverKey string) (domain.TWServer, error) { server, err := t.GetServer(ctx, versionCode, serverKey) if err != nil { return domain.TWServer{}, err } if !server.Open { return domain.TWServer{}, domain.TWServerNotFoundError{ VersionCode: versionCode, Key: serverKey, } } return server, nil } func (t *TWHelpHTTP) GetServer(ctx context.Context, versionCode, serverKey string) (domain.TWServer, error) { resp, err := t.client.GetServerWithResponse(ctx, versionCode, serverKey) if err != nil { return domain.TWServer{}, err } if resp.JSONDefault != nil { if slices.ContainsFunc(resp.JSONDefault.Errors, func(err twhelp.Error) bool { return err.Code == twhelp.ErrorCodeServerNotFound }) { return domain.TWServer{}, domain.TWServerNotFoundError{ VersionCode: versionCode, Key: serverKey, } } return domain.TWServer{}, t.convertErrors(resp.JSONDefault.Errors) } return t.convertServerToDomain(resp.JSON200.Data), nil } func (t *TWHelpHTTP) GetTribeByID(ctx context.Context, versionCode, serverKey string, id int) (domain.Tribe, error) { resp, err := t.client.GetTribeWithResponse(ctx, versionCode, serverKey, id) if err != nil { return domain.Tribe{}, err } if resp.JSONDefault != nil { if slices.ContainsFunc(resp.JSONDefault.Errors, func(err twhelp.Error) bool { return err.Code == twhelp.ErrorCodeTribeNotFound }) { return domain.Tribe{}, domain.TribeIDNotFoundError{ VersionCode: versionCode, ServerKey: serverKey, ID: id, } } return domain.Tribe{}, t.convertErrors(resp.JSONDefault.Errors) } return t.convertTribeToDomain(resp.JSON200.Data), nil } func (t *TWHelpHTTP) GetExistingTribeByTag(ctx context.Context, versionCode, serverKey, tribeTag string) (domain.Tribe, error) { deleted := false tags := []string{tribeTag} limit := 1 resp, err := t.client.ListTribesWithResponse(ctx, versionCode, serverKey, &twhelp.ListTribesParams{ Deleted: &deleted, Tag: &tags, Limit: &limit, }) if err != nil { return domain.Tribe{}, err } if resp.JSONDefault != nil { return domain.Tribe{}, t.convertErrors(resp.JSONDefault.Errors) } if len(resp.JSON200.Data) == 0 { return domain.Tribe{}, domain.TribeTagNotFoundError{ VersionCode: versionCode, ServerKey: serverKey, Tag: tribeTag, } } return t.convertTribeToDomain(resp.JSON200.Data[0]), nil } func (t *TWHelpHTTP) ListTribesByTag(ctx context.Context, versionCode, serverKey string, tribeTags []string) ([]domain.Tribe, error) { resp, err := t.client.ListTribesWithResponse(ctx, versionCode, serverKey, &twhelp.ListTribesParams{ Tag: &tribeTags, }) if err != nil { return nil, err } if resp.JSONDefault != nil { return nil, t.convertErrors(resp.JSONDefault.Errors) } res := make([]domain.Tribe, 0, len(resp.JSON200.Data)) for _, tr := range resp.JSON200.Data { res = append(res, t.convertTribeToDomain(tr)) } return res, nil } func (t *TWHelpHTTP) ListVillagesByCoords(ctx context.Context, versionCode, serverKey string, coords []string) ([]domain.Village, error) { resp, err := t.client.ListVillagesWithResponse(ctx, versionCode, serverKey, &twhelp.ListVillagesParams{ Coords: &coords, }) if err != nil { return nil, err } if resp.JSONDefault != nil { return nil, t.convertErrors(resp.JSONDefault.Errors) } res := make([]domain.Village, 0, len(resp.JSON200.Data)) for _, v := range resp.JSON200.Data { res = append(res, t.convertVillageToDomain(v)) } return res, nil } func (t *TWHelpHTTP) ListEnnoblementsSince(ctx context.Context, versionCode, serverKey string, since time.Time) ([]domain.Ennoblement, error) { sort := []string{ string(twhelp.ListEnnoblementsParamsSortCreatedAtASC), } resp, err := t.client.ListEnnoblementsWithResponse(ctx, versionCode, serverKey, &twhelp.ListEnnoblementsParams{ Sort: &sort, Since: &since, }) if err != nil { return nil, err } if resp.JSONDefault != nil { return nil, t.convertErrors(resp.JSONDefault.Errors) } res := make([]domain.Ennoblement, 0, len(resp.JSON200.Data)) for _, e := range resp.JSON200.Data { res = append(res, t.convertEnnoblementToDomain(e)) } return res, nil } func (t *TWHelpHTTP) convertVersionToDomain(v twhelp.Version) domain.TWVersion { return domain.TWVersion(v) } func (t *TWHelpHTTP) convertServerToDomain(s twhelp.Server) domain.TWServer { return domain.TWServer{ Key: s.Key, URL: s.Url, Open: s.Open, } } func (t *TWHelpHTTP) convertTribeToDomain(tr twhelp.Tribe) domain.Tribe { var deletedAt time.Time if tr.DeletedAt != nil { deletedAt = *tr.DeletedAt } return domain.Tribe{ ID: tr.Id, Tag: tr.Tag, Name: tr.Name, ProfileURL: tr.ProfileUrl, DeletedAt: deletedAt, } } func (t *TWHelpHTTP) convertTribeMetaToDomain(tr twhelp.TribeMeta) domain.TribeMeta { return domain.TribeMeta{ ID: tr.Id, Name: tr.Name, Tag: tr.Tag, ProfileURL: tr.ProfileUrl, } } func (t *TWHelpHTTP) convertNullTribeMetaToDomain(tr *twhelp.NullTribeMeta) domain.NullTribeMeta { res := domain.NullTribeMeta{ Valid: tr != nil, } if tr != nil { res.Tribe = t.convertTribeMetaToDomain(*tr) } return res } func (t *TWHelpHTTP) convertPlayerMetaToDomain(p twhelp.PlayerMeta) domain.PlayerMeta { return domain.PlayerMeta{ ID: p.Id, Name: p.Name, ProfileURL: p.ProfileUrl, Tribe: t.convertNullTribeMetaToDomain(p.Tribe), } } func (t *TWHelpHTTP) convertNullPlayerMetaToDomain(p *twhelp.NullPlayerMeta) domain.NullPlayerMeta { res := domain.NullPlayerMeta{ Valid: p != nil, } if p != nil { res.Player = t.convertPlayerMetaToDomain(*p) } return res } func (t *TWHelpHTTP) convertVillageToDomain(v twhelp.Village) domain.Village { return domain.Village{ ID: v.Id, FullName: v.FullName, ProfileURL: v.ProfileUrl, Points: v.Points, X: v.X, Y: v.Y, Player: t.convertNullPlayerMetaToDomain(v.Player), } } func (t *TWHelpHTTP) convertVillageMetaToDomain(v twhelp.VillageMeta) domain.VillageMeta { return domain.VillageMeta{ ID: v.Id, FullName: v.FullName, ProfileURL: v.ProfileUrl, Player: t.convertNullPlayerMetaToDomain(v.Player), } } func (t *TWHelpHTTP) convertEnnoblementToDomain(e twhelp.Ennoblement) domain.Ennoblement { return domain.Ennoblement{ ID: e.Id, Village: t.convertVillageMetaToDomain(e.Village), NewOwner: t.convertPlayerMetaToDomain(e.NewOwner), CreatedAt: e.CreatedAt, } } func (t *TWHelpHTTP) convertErrors(errs []twhelp.Error) error { if len(errs) == 0 { return nil } sep := "\n" n := len(sep) * (len(errs) - 1) for _, err := range errs { n += len(err.Message) } var b strings.Builder b.Grow(n) for i, err := range errs { if i > 0 { b.WriteString(sep) } b.WriteString(err.Message) } return errors.New(b.String()) }