package handlers import ( "net/http" "github.com/gin-gonic/gin" "github.com/google/uuid" "go.uber.org/zap" "veza-backend-api/internal/services" ) // BitrateHandler gère les requêtes pour l'adaptation de bitrate // T0349: Create Bitrate Adaptation Endpoint type BitrateHandler struct { adaptationService *services.BitrateAdaptationService commonHandler *CommonHandler } // NewBitrateHandler crée un nouveau handler de bitrate func NewBitrateHandler(adaptationService *services.BitrateAdaptationService, logger *zap.Logger) *BitrateHandler { return &BitrateHandler{ adaptationService: adaptationService, commonHandler: NewCommonHandler(logger), } } // AdaptBitrateRequest représente la requête pour adapter le bitrate type AdaptBitrateRequest struct { CurrentBitrate int `json:"current_bitrate" binding:"required"` Bandwidth int64 `json:"bandwidth" binding:"required"` BufferLevel float64 `json:"buffer_level" binding:"required"` } // AdaptBitrate gère la requête POST /api/v1/tracks/:id/bitrate/adapt // Reçoit les métriques de streaming et retourne le bitrate recommandé func (h *BitrateHandler) AdaptBitrate(c *gin.Context) { // Récupérer l'ID de l'utilisateur depuis le contexte (défini par le middleware d'authentification) userID := c.MustGet("user_id").(uuid.UUID) if userID == uuid.Nil { c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"}) return } // Récupérer l'ID du track depuis les paramètres de l'URL trackIDStr := c.Param("id") trackID, err := uuid.Parse(trackIDStr) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid track id"}) return } // Valider et parser le body de la requête var req AdaptBitrateRequest if appErr := h.commonHandler.BindAndValidateJSON(c, &req); appErr != nil { RespondWithAppError(c, appErr) return } // Appeler le service d'adaptation de bitrate newBitrate, err := h.adaptationService.AdaptBitrate( c.Request.Context(), trackID, userID, req.CurrentBitrate, req.Bandwidth, req.BufferLevel, ) if err != nil { // Le service retourne des erreurs de validation avec des messages spécifiques // On peut distinguer les erreurs de validation des erreurs internes if err.Error() == "invalid track ID: 0" || err.Error() == "invalid user ID: nil UUID" || err.Error() == "invalid current bitrate: 0" || err.Error()[:14] == "invalid buffer" { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } // Retourner le bitrate recommandé c.JSON(http.StatusOK, gin.H{"recommended_bitrate": newBitrate}) } // GetAnalytics gère la requête GET /api/v1/tracks/:id/bitrate/analytics // Retourne les statistiques d'adaptation de bitrate pour un track // T0354: Create Bitrate Adaptation Analytics Endpoint func (h *BitrateHandler) GetAnalytics(c *gin.Context) { // Récupérer l'ID du track depuis les paramètres de l'URL trackIDStr := c.Param("id") trackID, err := uuid.Parse(trackIDStr) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid track id"}) return } // Récupérer les analytics depuis le service analytics, err := h.adaptationService.GetAnalytics(c.Request.Context(), trackID) if err != nil { if err.Error() == "invalid track ID: 0" { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid track id"}) return } c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } // Retourner les analytics c.JSON(http.StatusOK, gin.H{"analytics": analytics}) }