package handler import ( "fmt" "net/http" "strings" "time" "github.com/google/uuid" "git.kundeng.us/phoenix/textsender-api/internal/store" "git.kundeng.us/phoenix/textsender-models/pkg/message/scheduling" ) type RequestAddScheduledMessage struct { Scheduled time.Time `json:"scheduled"` Created time.Time `json:"created"` Status string `json:"status"` UserId uuid.UUID `json:"user_id"` } type AddScheduledMessageResponse struct { Message string `json:"message"` Data []scheduling.ScheduledMessage `json:"data"` } type ScheduledMessageHandler struct { ScheduledMessageStore store.ScheduledMessageStore } func NewScheduledMessageHandler(str store.ScheduledMessageStore) *ScheduledMessageHandler { return &ScheduledMessageHandler{ScheduledMessageStore: str} } func (c *ScheduledMessageHandler) AddScheduledMessage(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } var req RequestAddScheduledMessage if err := ExtractFromRequest(r, &req); err != nil { http.Error(w, "Invalid JSON: "+err.Error(), http.StatusBadRequest) } defer r.Body.Close() scheduledMessage := scheduling.ScheduledMessage{Scheduled: req.Scheduled, Status: req.Status, UserId: req.UserId} var statusCode int var resp AddScheduledMessageResponse if scheduledMessage.UserId == uuid.Nil { statusCode = http.StatusBadRequest resp.Message = "No UserId" } else { ctx := r.Context() if validStatus, err := isStatusValid(&scheduledMessage); err == nil { if validStatus { if valid, err := isScheduledTimeValid(&scheduledMessage); err == nil && valid { if err = c.ScheduledMessageStore.CreateScheduledMessage(ctx, &scheduledMessage); err == nil { statusCode = http.StatusCreated resp.Data = append(resp.Data, scheduledMessage) resp.Message = "Successful" } else { statusCode = http.StatusInternalServerError resp.Message = err.Error() } } else { statusCode = http.StatusBadRequest resp.Message = "Invalid scheduled time" } } else { statusCode = http.StatusBadRequest resp.Message = "Invalid status" } } else { statusCode = http.StatusInternalServerError resp.Message = err.Error() } } RespondWithJSON(w, statusCode, &resp) } func isScheduledTimeValid(schMsg *scheduling.ScheduledMessage) (bool, error) { now := time.Now() timeCutOff := now.Add(-5 * time.Minute) futureCutOff := now.Add((24 * 7) * time.Hour) if schMsg.Scheduled.After(timeCutOff) { if schMsg.Scheduled.Before(futureCutOff) { return true, nil } else { return false, fmt.Errorf("Scheduled Time is too far in the future") } } else { return false, nil } } func isStatusValid(schMsg *scheduling.ScheduledMessage) (bool, error) { schMsg.Status = strings.ToUpper(schMsg.Status) if schMsg.Status == scheduling.Pending { return true, nil } else { return false, fmt.Errorf("Status is not valid for creating scheduled message %s", schMsg.Status) } }