// // APIv2_12.swift // iKeyMon // // Created by tracer on 13.11.25. // import Foundation extension APIv2_12 { struct Load: Codable { let current: LoadMetrics let historical: [LoadMetrics] struct LoadMetrics: Codable { let oneMinute: Double let fiveMinute: Double let fifteenMinute: Double let timestamp: Date enum CodingKeys: String, CodingKey { case oneMinute = "load_1" case fiveMinute = "load_5" case fifteenMinute = "load_15" case timestamp } } } struct Memory: Codable { let system: SystemMemory let swap: SwapMemory? struct SystemMemory: Codable { let total: Int64 let used: Int64 let free: Int64 let available: Int64 let buffers: Int64? let cached: Int64? } struct SwapMemory: Codable { let total: Int64 let used: Int64 let free: Int64 } } struct Utilization: Codable { let cpu: CPUUtilization let memory: MemoryUtilization let disk: [DiskUtilization] let network: [NetworkUtilization]? struct CPUUtilization: Codable { let overall: Double let cores: [Double] let processes: [ProcessInfo]? struct ProcessInfo: Codable { let pid: Int let name: String let cpuPercent: Double enum CodingKeys: String, CodingKey { case pid case name case cpuPercent = "cpu_percent" } } } struct MemoryUtilization: Codable { let percent: Double let topProcesses: [ProcessMemoryInfo]? struct ProcessMemoryInfo: Codable { let pid: Int let name: String let memoryMB: Double enum CodingKeys: String, CodingKey { case pid case name case memoryMB = "memory_mb" } } } struct DiskUtilization: Codable { let device: String let mountpoint: String let usedPercent: Double let totalBytes: Int64 let usedBytes: Int64 let freeBytes: Int64 enum CodingKeys: String, CodingKey { case device case mountpoint case usedPercent = "used_percent" case totalBytes = "total_bytes" case usedBytes = "used_bytes" case freeBytes = "free_bytes" } } struct NetworkUtilization: Codable { let interface: String let bytesIn: Int64 let bytesOut: Int64 let packetsIn: Int64 let packetsOut: Int64 enum CodingKeys: String, CodingKey { case interface case bytesIn = "bytes_in" case bytesOut = "bytes_out" case packetsIn = "packets_in" case packetsOut = "packets_out" } } } } class APIv2_12: BaseAPIClient, ServerAPIProtocol { typealias LoadType = APIv2_12.Load typealias MemoryType = APIv2_12.Memory typealias UtilizationType = APIv2_12.Utilization private enum Endpoint: String { case systemInfo = "/api/v2.12/system/info" case load = "/api/v2.12/metrics/load" case memory = "/api/v2.12/metrics/memory" case utilization = "/api/v2.12/metrics/utilization" func url(baseURL: URL) -> URL { return baseURL.appendingPathComponent(self.rawValue) } } func fetchSystemInfo() async throws -> SystemInfo { let url = Endpoint.systemInfo.url(baseURL: baseURL) let request = URLRequest(url: url) return try await performRequest(request, responseType: SystemInfo.self) } func fetchLoad() async throws -> LoadType { let url = Endpoint.load.url(baseURL: baseURL) var request = URLRequest(url: url) request.setValue("application/json", forHTTPHeaderField: "Accept") return try await performRequest(request, responseType: LoadType.self) } func fetchMemory() async throws -> MemoryType { let url = Endpoint.memory.url(baseURL: baseURL) var request = URLRequest(url: url) request.setValue("application/json", forHTTPHeaderField: "Accept") return try await performRequest(request, responseType: MemoryType.self) } func fetchUtilization() async throws -> UtilizationType { let url = Endpoint.utilization.url(baseURL: baseURL) var request = URLRequest(url: url) request.setValue("application/json", forHTTPHeaderField: "Accept") return try await performRequest(request, responseType: UtilizationType.self) } }