package handler import ( "net/http" "github.com/google/uuid" "git.kundeng.us/phoenix/textsender-api/internal/store" "git.kundeng.us/phoenix/textsender-models/pkg/message/scheduling" ) type RequestScheduledMessageStatus struct { ScheduledMessageId uuid.UUID `json:"scheduled_message_id"` Status string `json:"status"` } type ScheduledMessageChange struct { OldStatus string `json:"old_status"` ScheduledMessage scheduling.ScheduledMessage `json:"scheduled_message"` } type ScheduledMessageStatusResponse struct { Message string `json:"message"` Data []ScheduledMessageChange `json:"data"` } type ScheduledMessageStatusHandler struct { ScheduledMessageEventStore store.ScheduledMessageEventStore ScheduledMessageStore store.ScheduledMessageStore } func NewScheduledMessageStatusHandler(str store.ScheduledMessageEventStore, schStore store.ScheduledMessageStore) *ScheduledMessageStatusHandler { return &ScheduledMessageStatusHandler{ScheduledMessageEventStore: str, ScheduledMessageStore: schStore} } func (s *ScheduledMessageStatusHandler) UpdateStatus(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPatch { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } var req RequestScheduledMessageStatus if err := ExtractFromRequest(r, &req); err != nil { http.Error(w, "Invalid JSON: "+err.Error(), http.StatusBadRequest) } defer r.Body.Close() var statusCode int var resp ScheduledMessageStatusResponse if req.ScheduledMessageId == uuid.Nil { statusCode = http.StatusBadRequest resp.Message = "Scheduled messaged Id is nil" } else if len(req.Status) == 0 { statusCode = http.StatusBadRequest resp.Message = "No status provided" } else { ctx := r.Context() if schMsg, err := s.ScheduledMessageStore.Get(ctx, req.ScheduledMessageId); err != nil { statusCode = http.StatusInternalServerError resp.Message = err.Error() } else { if schMsg.Status == scheduling.Done { statusCode = http.StatusNotFound resp.Message = "Scheduled message has already completed" } else { switch req.Status { case scheduling.Pending: { if schMsg.Status == scheduling.Processing { statusCode = http.StatusBadRequest resp.Message = "Message is currently processing" } else { if returnedStatus, err := s.ScheduledMessageStore.UpdateStatus(ctx, schMsg.Id, req.Status); err != nil { statusCode = http.StatusInternalServerError resp.Message = err.Error() } else { chg := initScheduledMessageChange(schMsg, schMsg.Status, *returnedStatus) statusCode = http.StatusOK resp.Message = "Successful" resp.Data = append(resp.Data, chg) } } } case scheduling.Ready: { if events, err := s.ScheduledMessageEventStore.GetWithScheduleMessageId(ctx, schMsg.Id); err != nil { statusCode = http.StatusInternalServerError resp.Message = err.Error() } else { oldStatus := schMsg.Status if schMsg.Status != scheduling.Processing && schMsg.Status != scheduling.Ready { // Update status if len(events) > 0 { if returnedStatus, err := s.ScheduledMessageStore.UpdateStatus(ctx, schMsg.Id, req.Status); err != nil { statusCode = http.StatusInternalServerError resp.Message = err.Error() } else { chg := initScheduledMessageChange(schMsg, oldStatus, *returnedStatus) statusCode = http.StatusOK resp.Message = "Successful" resp.Data = append(resp.Data, chg) } } else { statusCode = http.StatusInternalServerError resp.Message = "Not enough scheduled message events" } } else { if schMsg.Status == scheduling.Processing { statusCode = http.StatusBadRequest resp.Message = "Scheduled messages are processing" } else { statusCode = http.StatusNotModified resp.Message = "Status is already set" } } } } case scheduling.Processing, scheduling.Done: { if events, err := s.ScheduledMessageEventStore.GetWithScheduleMessageId(ctx, schMsg.Id); err != nil { statusCode = http.StatusInternalServerError resp.Message = err.Error() } else { if len(events) > 0 { if returnedStatus, err := s.ScheduledMessageStore.UpdateStatus(ctx, schMsg.Id, req.Status); err != nil { statusCode = http.StatusInternalServerError resp.Message = err.Error() } else { chg := initScheduledMessageChange(schMsg, schMsg.Status, *returnedStatus) statusCode = http.StatusOK resp.Message = "Successful" resp.Data = append(resp.Data, chg) } } else { statusCode = http.StatusInternalServerError resp.Message = "Not enough scheduled message events" } } } } } } } RespondWithJSON(w, statusCode, &resp) } func initScheduledMessageChange(schMsg *scheduling.ScheduledMessage, oldStatus, newStatus string) ScheduledMessageChange { schMsg.Status = newStatus return ScheduledMessageChange{OldStatus: oldStatus, ScheduledMessage: *schMsg} }