package api import ( "fmt" "time" "git.threefold.info/herocode/heroagent/pkg/system/stats" "github.com/gofiber/fiber/v2" ) // UptimeProvider defines an interface for getting system uptime type UptimeProvider interface { GetUptime() string } // AdminHandler handles admin-related API routes type AdminHandler struct { uptimeProvider UptimeProvider statsManager *stats.StatsManager } // NewAdminHandler creates a new AdminHandler func NewAdminHandler(uptimeProvider UptimeProvider, statsManager *stats.StatsManager) *AdminHandler { // If statsManager is nil, create a new one with default settings if statsManager == nil { var err error statsManager, err = stats.NewStatsManagerWithDefaults() if err != nil { // Log the error but continue with nil statsManager fmt.Printf("Error creating StatsManager: %v\n", err) } } return &AdminHandler{ uptimeProvider: uptimeProvider, statsManager: statsManager, } } // RegisterRoutes registers all admin API routes func (h *AdminHandler) RegisterRoutes(app *fiber.App) { // API endpoints admin := app.Group("/api") // @Summary Get hardware stats // @Description Get hardware statistics in JSON format // @Tags admin // @Accept json // @Produce json // @Success 200 {object} map[string]interface{} // @Failure 500 {object} ErrorResponse // @Router /api/hardware-stats [get] admin.Get("/hardware-stats", h.getHardwareStatsJSON) // @Summary Get process stats // @Description Get process statistics in JSON format // @Tags admin // @Accept json // @Produce json // @Success 200 {object} map[string]interface{} // @Failure 500 {object} ErrorResponse // @Router /api/process-stats [get] admin.Get("/process-stats", h.getProcessStatsJSON) } // getProcessStatsJSON returns process statistics in JSON format for API consumption func (h *AdminHandler) getProcessStatsJSON(c *fiber.Ctx) error { // Get process stats from the StatsManager (limit to top 30 processes) var processData *stats.ProcessStats var err error if h.statsManager != nil { processData, err = h.statsManager.GetProcessStats(30) } else { // Fallback to direct function call if StatsManager is not available processData, err = stats.GetProcessStats(30) } if err != nil { return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "success": false, "error": "Failed to get process stats: " + err.Error(), }) } // Convert to []fiber.Map for JSON response processStats := make([]fiber.Map, len(processData.Processes)) for i, proc := range processData.Processes { processStats[i] = fiber.Map{ "pid": proc.PID, "name": proc.Name, "status": proc.Status, "cpu_percent": proc.CPUPercent, "memory_mb": proc.MemoryMB, "create_time_str": proc.CreateTime, "is_current": proc.IsCurrent, } } // Return JSON response return c.JSON(fiber.Map{ "success": true, "processes": processStats, "timestamp": time.Now().Unix(), }) } // getHardwareStatsJSON returns hardware stats in JSON format for API consumption func (h *AdminHandler) getHardwareStatsJSON(c *fiber.Ctx) error { // Get hardware stats from the StatsManager var hardwareStats map[string]interface{} if h.statsManager != nil { hardwareStats = h.statsManager.GetHardwareStatsJSON() } else { // Fallback to direct function call if StatsManager is not available hardwareStats = stats.GetHardwareStatsJSON() } // Convert to fiber.Map for JSON response response := fiber.Map{ "success": true, } for k, v := range hardwareStats { response[k] = v } // Return JSON response return c.JSON(response) }