package mock import ( "fmt" "math/rand" "time" "spore-gateway/pkg/client" "spore-gateway/pkg/registry" ) // GenerateMockClusterMembers generates mock cluster member data func GenerateMockClusterMembers(nodes map[string]*NodeInfo) []client.ClusterMember { members := make([]client.ClusterMember, 0, len(nodes)) for _, node := range nodes { member := client.ClusterMember{ IP: node.IP, Hostname: node.Hostname, Status: string(node.Status), Latency: node.Latency, LastSeen: node.LastSeen.Unix(), Labels: node.Labels, Resources: map[string]interface{}{ "freeHeap": 32768 + rand.Intn(32768), "cpuFreqMHz": 80 + rand.Intn(160), "flashChipSize": 4194304, }, } members = append(members, member) } return members } // GenerateMockTaskStatus generates mock task status data func GenerateMockTaskStatus() *client.TaskStatusResponse { tasks := []client.TaskInfo{ { Name: "HeartbeatTask", Interval: 5000, Enabled: true, Running: true, AutoStart: true, }, { Name: "SensorReadTask", Interval: 10000, Enabled: true, Running: true, AutoStart: true, }, { Name: "StatusUpdateTask", Interval: 30000, Enabled: true, Running: false, AutoStart: false, }, { Name: "CleanupTask", Interval: 60000, Enabled: false, Running: false, AutoStart: false, }, } activeTasks := 0 for _, task := range tasks { if task.Running { activeTasks++ } } return &client.TaskStatusResponse{ Summary: client.TaskSummary{ TotalTasks: len(tasks), ActiveTasks: activeTasks, }, Tasks: tasks, System: client.SystemInfo{ FreeHeap: 32768 + int64(rand.Intn(32768)), Uptime: int64(time.Now().Unix() - 3600*24), // 24 hours uptime }, } } // GenerateMockSystemStatus generates mock system status data func GenerateMockSystemStatus(labels map[string]string) *client.SystemStatusResponse { return &client.SystemStatusResponse{ FreeHeap: 32768 + int64(rand.Intn(32768)), ChipID: int64(rand.Int31()), SDKVersion: "3.1.0", CPUFreqMHz: 80 + rand.Intn(160), FlashChipSize: 4194304, Labels: labels, } } // GenerateMockCapabilities generates mock API endpoint capabilities func GenerateMockCapabilities() *client.CapabilitiesResponse { return &client.CapabilitiesResponse{ Endpoints: []client.EndpointInfo{ { URI: "/api/node/status", Method: "GET", Parameters: []client.ParameterInfo{ { Name: "detailed", Type: "boolean", Required: false, Description: "Include detailed system information", Location: "query", Default: "false", }, }, }, { URI: "/api/cluster/members", Method: "GET", Parameters: []client.ParameterInfo{}, }, { URI: "/api/tasks/status", Method: "GET", Parameters: []client.ParameterInfo{}, }, { URI: "/api/node/update", Method: "POST", Parameters: []client.ParameterInfo{ { Name: "firmware", Type: "file", Required: true, Description: "Firmware binary file", Location: "body", }, }, }, { URI: "/api/node/config", Method: "POST", Parameters: []client.ParameterInfo{ { Name: "labels", Type: "json", Required: true, Description: "Node labels in JSON format", Location: "body", }, }, }, { URI: "/api/sensors/read", Method: "GET", Parameters: []client.ParameterInfo{ { Name: "sensor", Type: "string", Required: false, Description: "Specific sensor to read", Location: "query", Values: []string{"temperature", "humidity", "pressure"}, }, }, }, }, } } // GenerateMockFirmwareList generates mock firmware registry data func GenerateMockFirmwareList() []registry.GroupedFirmware { return []registry.GroupedFirmware{ { Name: "spore-firmware", Firmware: []registry.FirmwareRecord{ { Name: "spore-firmware", Version: "1.0.0", Size: 524288, Labels: map[string]string{ "stable": "true", "env": "production", }, Path: "/firmware/spore-firmware/1.0.0", }, { Name: "spore-firmware", Version: "1.1.0", Size: 548864, Labels: map[string]string{ "stable": "true", "env": "production", }, Path: "/firmware/spore-firmware/1.1.0", }, { Name: "spore-firmware", Version: "1.2.0", Size: 573440, Labels: map[string]string{ "stable": "false", "env": "beta", }, Path: "/firmware/spore-firmware/1.2.0", }, }, }, { Name: "sensor-firmware", Firmware: []registry.FirmwareRecord{ { Name: "sensor-firmware", Version: "2.0.0", Size: 262144, Labels: map[string]string{ "stable": "true", "type": "sensor", }, Path: "/firmware/sensor-firmware/2.0.0", }, { Name: "sensor-firmware", Version: "2.1.0", Size: 286720, Labels: map[string]string{ "stable": "true", "type": "sensor", }, Path: "/firmware/sensor-firmware/2.1.0", }, }, }, } } // GenerateMockFirmwareBinary generates mock firmware binary data func GenerateMockFirmwareBinary(size int) []byte { // Generate some pseudo-random but deterministic binary data data := make([]byte, size) for i := range data { data[i] = byte(i % 256) } return data } // NodeInfo is an alias to avoid import cycle type NodeInfo struct { IP string Hostname string Status string Latency int64 LastSeen time.Time Labels map[string]string } // ResourceMetrics represents resource usage metrics for a node type ResourceMetrics struct { Timestamp int64 `json:"timestamp"` NodeIP string `json:"node_ip"` Hostname string `json:"hostname"` CPU CPUMetrics `json:"cpu"` Memory MemoryMetrics `json:"memory"` Network NetworkMetrics `json:"network"` Flash FlashMetrics `json:"flash"` Labels map[string]string `json:"labels"` } // CPUMetrics represents CPU usage metrics type CPUMetrics struct { Frequency int `json:"frequency_mhz"` UsagePercent float64 `json:"usage_percent"` Temperature float64 `json:"temperature_c,omitempty"` } // MemoryMetrics represents memory usage metrics type MemoryMetrics struct { Total int64 `json:"total_bytes"` Free int64 `json:"free_bytes"` Used int64 `json:"used_bytes"` UsagePercent float64 `json:"usage_percent"` } // NetworkMetrics represents network usage metrics type NetworkMetrics struct { BytesSent int64 `json:"bytes_sent"` BytesReceived int64 `json:"bytes_received"` PacketsSent int64 `json:"packets_sent"` PacketsRecv int64 `json:"packets_received"` RSSI int `json:"rssi_dbm,omitempty"` SignalQuality float64 `json:"signal_quality_percent,omitempty"` } // FlashMetrics represents flash storage metrics type FlashMetrics struct { Total int64 `json:"total_bytes"` Used int64 `json:"used_bytes"` Free int64 `json:"free_bytes"` UsagePercent float64 `json:"usage_percent"` } // MonitoringResourcesResponse represents the monitoring resources endpoint response type MonitoringResourcesResponse struct { Timestamp string `json:"timestamp"` Nodes []ResourceMetrics `json:"nodes"` Summary ResourceSummary `json:"summary"` } // ResourceSummary provides aggregate statistics across all nodes type ResourceSummary struct { TotalNodes int `json:"total_nodes"` AvgCPUUsage float64 `json:"avg_cpu_usage_percent"` AvgMemoryUsage float64 `json:"avg_memory_usage_percent"` AvgFlashUsage float64 `json:"avg_flash_usage_percent"` TotalBytesSent int64 `json:"total_bytes_sent"` TotalBytesRecv int64 `json:"total_bytes_received"` } // GenerateMockMonitoringResources generates meaningful mock monitoring data for all nodes func GenerateMockMonitoringResources(nodes map[string]*NodeInfo) *MonitoringResourcesResponse { now := time.Now() metrics := make([]ResourceMetrics, 0, len(nodes)) var totalCPU, totalMemoryPercent, totalFlash float64 var totalBytesSent, totalBytesRecv int64 for _, node := range nodes { // Generate realistic resource usage based on node characteristics cpuFreq := 80 + rand.Intn(160) cpuUsage := 15.0 + rand.Float64()*45.0 // 15-60% usage // Memory metrics nodeMemoryTotal := int64(65536 + rand.Intn(65536)) // 64-128KB freeMemory := int64(32768 + rand.Intn(32768)) // 32-64KB free usedMemory := nodeMemoryTotal - freeMemory memoryUsagePercent := float64(usedMemory) / float64(nodeMemoryTotal) * 100 // Flash metrics flashTotal := int64(4194304) // 4MB flashUsed := int64(1048576 + rand.Intn(2097152)) // 1-3MB used flashFree := flashTotal - flashUsed flashUsagePercent := float64(flashUsed) / float64(flashTotal) * 100 // Network metrics (simulating accumulated traffic) bytesSent := int64(1000000 + rand.Intn(5000000)) // 1-6MB bytesRecv := int64(2000000 + rand.Intn(8000000)) // 2-10MB packetsSent := int64(10000 + rand.Intn(50000)) packetsRecv := int64(15000 + rand.Intn(75000)) // WiFi signal metrics rssi := -30 - rand.Intn(60) // -30 to -90 dBm signalQuality := float64(100+rssi+90) / 60.0 * 100 // Convert RSSI to quality percentage if signalQuality < 0 { signalQuality = 0 } else if signalQuality > 100 { signalQuality = 100 } metric := ResourceMetrics{ Timestamp: now.Unix(), NodeIP: node.IP, Hostname: node.Hostname, CPU: CPUMetrics{ Frequency: cpuFreq, UsagePercent: cpuUsage, Temperature: 45.0 + rand.Float64()*20.0, // 45-65°C }, Memory: MemoryMetrics{ Total: nodeMemoryTotal, Free: freeMemory, Used: usedMemory, UsagePercent: memoryUsagePercent, }, Network: NetworkMetrics{ BytesSent: bytesSent, BytesReceived: bytesRecv, PacketsSent: packetsSent, PacketsRecv: packetsRecv, RSSI: rssi, SignalQuality: signalQuality, }, Flash: FlashMetrics{ Total: flashTotal, Used: flashUsed, Free: flashFree, UsagePercent: flashUsagePercent, }, Labels: node.Labels, } metrics = append(metrics, metric) // Accumulate for summary totalCPU += cpuUsage totalMemoryPercent += memoryUsagePercent totalFlash += flashUsagePercent totalBytesSent += bytesSent totalBytesRecv += bytesRecv } // Calculate averages nodeCount := len(nodes) var avgCPU, avgMemory, avgFlash float64 if nodeCount > 0 { avgCPU = totalCPU / float64(nodeCount) avgMemory = totalMemoryPercent / float64(nodeCount) avgFlash = totalFlash / float64(nodeCount) } return &MonitoringResourcesResponse{ Timestamp: now.Format(time.RFC3339), Nodes: metrics, Summary: ResourceSummary{ TotalNodes: nodeCount, AvgCPUUsage: avgCPU, AvgMemoryUsage: avgMemory, AvgFlashUsage: avgFlash, TotalBytesSent: totalBytesSent, TotalBytesRecv: totalBytesRecv, }, } } // GenerateMockProxyResponse generates a mock response for proxy calls func GenerateMockProxyResponse(method, uri string) map[string]interface{} { switch uri { case "/api/sensors/read": return map[string]interface{}{ "temperature": 22.5 + rand.Float64()*5, "humidity": 45.0 + rand.Float64()*20, "pressure": 1013.0 + rand.Float64()*10, "timestamp": time.Now().Unix(), } case "/api/led/control": return map[string]interface{}{ "status": "success", "message": "LED state updated", "state": "on", } default: return map[string]interface{}{ "status": "success", "message": fmt.Sprintf("Mock response for %s %s", method, uri), "data": map[string]interface{}{"mock": true}, } } }