package handler import ( "errors" "net/http" "os" "github.com/gin-gonic/gin" "github.com/go-playground/validator/v10" "github.com/google/uuid" "github.com/iliadenisov/galaxy/internal/controller" e "github.com/iliadenisov/galaxy/internal/error" "github.com/iliadenisov/galaxy/internal/model/rest" ) type CommandExecutor interface { GenerateGame([]string) (uuid.UUID, error) GameState() (rest.StateResponse, error) Execute(cmd ...Command) error } type Command func(controller.Ctrl) error type executor struct { cfg controller.Configurer } func initConfig() controller.Configurer { return func(p *controller.Param) { p.StoragePath = os.Getenv("STORAGE_PATH") } } func NewDefaultExecutor() CommandExecutor { return NewDefaultConfigExecutor(initConfig()) } func NewDefaultConfigExecutor(configurer controller.Configurer) CommandExecutor { return &executor{cfg: configurer} } func (e *executor) Execute(command ...Command) error { return controller.ExecuteCommand(e.cfg, func(c controller.Ctrl) error { for i := range command { if err := command[i](c); err != nil { return err } } return nil }) } func (e *executor) GenerateGame(races []string) (uuid.UUID, error) { return controller.GenerateGame(e.cfg, races) } func (e *executor) GameState() (rest.StateResponse, error) { s, err := controller.GameState(e.cfg) if err != nil { return rest.StateResponse{}, err } result := &rest.StateResponse{ ID: s.ID, Turn: s.Turn, Stage: s.Stage, Players: make([]rest.PlayerState, len(s.Players)), } for i := range s.Players { result.Players[i].ID = s.Players[i].ID result.Players[i].Name = s.Players[i].Name result.Players[i].Extinct = s.Players[i].Extinct } return *result, nil } func errorResponded(c *gin.Context, err error) bool { if err == nil { return false } var ge = new(e.GenericError) if v, ok := err.(validator.ValidationErrors); ok { c.JSON(http.StatusBadRequest, gin.H{"error": v.Error()}) return true } if errors.As(err, ge) { switch ge.Code { case e.ErrGameNotInitialized: c.Status(http.StatusNotImplemented) default: c.JSON(http.StatusInternalServerError, gin.H{"generic_error": ge.Error(), "code": ge.Code}) } } else { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) } return true }