package handlers import ( "fmt" "net/http" "strconv" "git.linuxforward.com/byop/byop-engine/models" "git.linuxforward.com/byop/byop-engine/services" "github.com/gin-gonic/gin" ) // ComponentHandler handles component-related operations type ComponentHandler struct { service *services.ComponentService } // NewComponentHandler creates a new ComponentHandler func NewComponentHandler(service *services.ComponentService) *ComponentHandler { return &ComponentHandler{ service: service, } } // RegisterRoutes registers routes for component operations func (h *ComponentHandler) RegisterRoutes(r *gin.RouterGroup) { r.GET("/", h.ListComponents) r.POST("/", h.CreateComponent) r.GET("/:id", h.GetComponent) r.PUT("/:id", h.UpdateComponent) r.DELETE("/:id", h.DeleteComponent) r.GET("/:id/deployments", h.GetComponentDeployments) } // ListComponents returns all components with optional filtering func (h *ComponentHandler) ListComponents(c *gin.Context) { filter := make(map[string]interface{}) // Attempt to bind query parameters, but allow empty filters if err := c.ShouldBindQuery(&filter); err != nil && len(filter) > 0 { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid query parameters"}) return } components, err := h.service.ListComponents(filter) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("Failed to list components: %v", err)}) return } c.JSON(http.StatusOK, components) } // CreateComponent creates a new component func (h *ComponentHandler) CreateComponent(c *gin.Context) { var component models.Component if err := c.ShouldBindJSON(&component); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("Invalid request body: %v", err)}) return } // Get the user ID from the context (set by auth middleware) userID, exists := c.Get("userID") if exists { component.CreatedBy = userID.(string) } if err := h.service.CreateComponent(&component); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("Failed to create component: %v", err)}) return } c.JSON(http.StatusCreated, component) } // GetComponent returns a specific component func (h *ComponentHandler) GetComponent(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseInt(idStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid component ID"}) return } component, err := h.service.GetComponent(id) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("Failed to fetch component: %v", err)}) return } if component == nil { c.JSON(http.StatusNotFound, gin.H{"error": "Component not found"}) return } c.JSON(http.StatusOK, component) } // UpdateComponent updates a component func (h *ComponentHandler) UpdateComponent(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseInt(idStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid component ID"}) return } var updatedComponent models.Component if err := c.ShouldBindJSON(&updatedComponent); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("Invalid request body: %v", err)}) return } // Ensure the ID matches the URL parameter updatedComponent.ID = id if err := h.service.UpdateComponent(&updatedComponent); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("Failed to update component: %v", err)}) return } c.JSON(http.StatusOK, updatedComponent) } // DeleteComponent deletes a component func (h *ComponentHandler) DeleteComponent(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseInt(idStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid component ID"}) return } if err := h.service.DeleteComponent(id); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("Failed to delete component: %v", err)}) return } c.Status(http.StatusNoContent) } // GetComponentDeployments returns all deployments for a component func (h *ComponentHandler) GetComponentDeployments(c *gin.Context) { idStr := c.Param("id") id, err := strconv.ParseInt(idStr, 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid component ID"}) return } deployments, err := h.service.GetComponentDeployments(id) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("Failed to fetch component deployments: %v", err)}) return } c.JSON(http.StatusOK, deployments) }