import Foundation
import IOKit

/// Device-Info für den aktuellen Mac.
/// Wird für /api/magic/register benötigt.
struct MacDeviceInfo {
    let deviceId: String       // IOPlatformUUID
    let hostname: String       // Host.current().localizedName
    let model: String          // hw.model via sysctl
    let osVersion: String      // ProductVersion
}

enum MacDeviceDetectorError: Error, LocalizedError {
    case platformUUIDNotFound
    case sysctlFailed(String)
    
    var errorDescription: String? {
        switch self {
        case .platformUUIDNotFound:
            return "IOPlatformUUID nicht gefunden"
        case .sysctlFailed(let msg):
            return "sysctl fehlgeschlagen: \(msg)"
        }
    }
}

/// Erkennt Mac-Hardware-Infos via IOKit + sysctl.
enum MacDeviceDetector {
    
    /// Liest IOPlatformUUID — eindeutige Hardware-ID des Mac.
    static func platformUUID() throws -> String {
        let service = IOServiceGetMatchingService(
            kIOMainPortDefault,
            IOServiceMatching("IOPlatformExpertDevice")
        )
        
        guard service != 0 else {
            throw MacDeviceDetectorError.platformUUIDNotFound
        }
        
        defer { IOObjectRelease(service) }
        
        guard let uuidCF = IORegistryEntryCreateCFProperty(
            service,
            "IOPlatformUUID" as CFString,
            kCFAllocatorDefault,
            0
        )?.takeRetainedValue() as? String else {
            throw MacDeviceDetectorError.platformUUIDNotFound
        }
        
        return uuidCF
    }
    
    /// Liest hw.model via sysctl (z.B. "MacBookPro18,3").
    static func hwModel() throws -> String {
        var size: size_t = 0
        sysctlbyname("hw.model", nil, &size, nil, 0)
        
        var model = [CChar](repeating: 0, count: size)
        guard sysctlbyname("hw.model", &model, &size, nil, 0) == 0 else {
            throw MacDeviceDetectorError.sysctlFailed("hw.model read failed")
        }
        
        return String(cString: model)
    }
    
    /// Sammelt alle Infos für /api/magic/register.
    static func detect() throws -> MacDeviceInfo {
        let deviceId = try platformUUID()
        let hostname = Host.current().localizedName ?? "Unknown Mac"
        let model = try hwModel()
        let osVersion = ProcessInfo.processInfo.operatingSystemVersionString
        
        return MacDeviceInfo(
            deviceId: deviceId,
            hostname: hostname,
            model: model,
            osVersion: osVersion
        )
    }
}
