package notify import ( flatbuffers "github.com/google/flatbuffers/go" "scrabble/backend/internal/engine" "scrabble/pkg/wire" ) // The builders below encode the nested wire tables embedded in enriched event // payloads. They map the domain's already-resolved values (notify.* payload structs // and the decoded engine.MoveRecord) to the neutral scrabble/pkg/wire structs and // delegate the FlatBuffers construction to package wire — the single definition of the // nested-table layout shared with the gateway transcoder. Each returns the offset of // the table it built; callers must build every nested table before opening the parent. // toWireGame maps a GameSummary to the shared wire.GameView. func toWireGame(g GameSummary) wire.GameView { seats := make([]wire.SeatView, len(g.Seats)) for i, s := range g.Seats { seats[i] = wire.SeatView{ Seat: s.Seat, AccountID: s.AccountID, Score: s.Score, HintsUsed: s.HintsUsed, IsWinner: s.IsWinner, DisplayName: s.DisplayName, } } return wire.GameView{ ID: g.ID, Variant: g.Variant, DictVersion: g.DictVersion, Status: g.Status, Players: g.Players, ToMove: g.ToMove, TurnTimeoutSecs: g.TurnTimeoutSecs, MoveCount: g.MoveCount, EndReason: g.EndReason, Seats: seats, LastActivityUnix: g.LastActivityUnix, } } // buildGameView builds a GameView table from a GameSummary and returns its offset. func buildGameView(b *flatbuffers.Builder, g GameSummary) flatbuffers.UOffsetT { return wire.BuildGameView(b, toWireGame(g)) } // buildMoveRecord builds a MoveRecord table from a decoded engine move and returns its // offset (Count is the engine count: the number of tiles swapped on an exchange, zero // otherwise). func buildMoveRecord(b *flatbuffers.Builder, m engine.MoveRecord) flatbuffers.UOffsetT { tiles := make([]wire.TileRecord, len(m.Tiles)) for i, t := range m.Tiles { tiles[i] = wire.TileRecord{Row: t.Row, Col: t.Col, Letter: t.Letter, Blank: t.Blank} } return wire.BuildMoveRecord(b, wire.MoveRecord{ Player: m.Player, Action: m.Action.String(), Dir: m.Dir.String(), MainRow: m.MainRow, MainCol: m.MainCol, Tiles: tiles, Words: m.Words, Count: m.Count, Score: m.Score, Total: m.Total, }) } // buildStateView builds a StateView table from a PlayerState and returns its offset. func buildStateView(b *flatbuffers.Builder, s PlayerState) flatbuffers.UOffsetT { alphabet := make([]wire.AlphabetEntry, len(s.Alphabet)) for i, e := range s.Alphabet { alphabet[i] = wire.AlphabetEntry{Index: e.Index, Letter: e.Letter, Value: e.Value} } return wire.BuildStateView(b, wire.StateView{ Game: toWireGame(s.Game), Seat: s.Seat, Rack: s.Rack, BagLen: s.BagLen, HintsRemaining: s.HintsRemaining, Alphabet: alphabet, }) } // buildAccountRef builds an AccountRef table and returns its offset. func buildAccountRef(b *flatbuffers.Builder, a AccountRef) flatbuffers.UOffsetT { return wire.BuildAccountRef(b, wire.AccountRef{AccountID: a.AccountID, DisplayName: a.DisplayName}) } // buildInvitation builds an Invitation table from an InvitationSummary and returns its offset. func buildInvitation(b *flatbuffers.Builder, inv InvitationSummary) flatbuffers.UOffsetT { invitees := make([]wire.InvitationInvitee, len(inv.Invitees)) for i, iv := range inv.Invitees { invitees[i] = wire.InvitationInvitee{ AccountID: iv.AccountID, DisplayName: iv.DisplayName, Seat: iv.Seat, Response: iv.Response, } } return wire.BuildInvitation(b, wire.Invitation{ ID: inv.ID, Inviter: wire.AccountRef{AccountID: inv.Inviter.AccountID, DisplayName: inv.Inviter.DisplayName}, Invitees: invitees, Variant: inv.Variant, TurnTimeoutSecs: inv.TurnTimeoutSecs, HintsAllowed: inv.HintsAllowed, HintsPerPlayer: inv.HintsPerPlayer, DropoutTiles: inv.DropoutTiles, Status: inv.Status, GameID: inv.GameID, ExpiresAtUnix: inv.ExpiresAtUnix, }) }