import XCTest
@testable import SiliconPulseCore

final class HealthModelTests: XCTestCase {
    func test_gpuTemperatureMapsToWhiteYellowRedBuckets() {
        XCTAssertEqual(HealthModel.gpuBucket(for: nil), .white)
        XCTAssertEqual(HealthModel.gpuBucket(for: 64), .white)
        XCTAssertEqual(HealthModel.gpuBucket(for: 75), .yellow)
        XCTAssertEqual(HealthModel.gpuBucket(for: 90), .red)
    }

    func test_memoryCriticalWinsMenubarEvenWhenGpuIsCool() {
        let snapshot = SystemSnapshot(
            cpuTemperatureCelsius: 110,
            gpuTemperatureCelsius: 34,
            memoryPressureFraction: 0.92,
            memoryPressureLevel: .critical,
            thermalState: .critical)

        let model = HealthModel.model(for: snapshot)

        XCTAssertEqual(model.menubar.domain, .memory)
        XCTAssertEqual(model.menubar.bucket, .red)
    }

    func test_cpuTemperatureDoesNotDriveMenubarSeverity() {
        let snapshot = SystemSnapshot(
            cpuTemperatureCelsius: 120,
            gpuTemperatureCelsius: 42,
            memoryPressureFraction: 0.2,
            memoryPressureLevel: .normal,
            thermalState: .critical)

        let model = HealthModel.model(for: snapshot)

        XCTAssertEqual(model.cpu.bucket, .red)
        XCTAssertEqual(model.menubar.bucket, .white)
        XCTAssertNotEqual(model.menubar.domain, .cpu)
    }

    func test_menubarSelectionUsesOnlyGpuAndMemoryPressureWithMemoryTieBreak() {
        let gpuHigh = SystemSnapshot(
            cpuTemperatureCelsius: 35,
            gpuTemperatureCelsius: 78,
            memoryPressureFraction: 0.2,
            memoryPressureLevel: .normal,
            thermalState: .nominal)

        XCTAssertEqual(HealthModel.model(for: gpuHigh).menubar.domain, .gpu)
        XCTAssertEqual(HealthModel.model(for: gpuHigh).menubar.bucket, .yellow)

        let bothYellow = SystemSnapshot(
            cpuTemperatureCelsius: 35,
            gpuTemperatureCelsius: 78,
            memoryPressureFraction: 0.66,
            memoryPressureLevel: .warning,
            thermalState: .nominal)

        XCTAssertEqual(HealthModel.model(for: bothYellow).menubar.domain, .memory)
    }

    func test_fillFractionsClampAndNilTemperatureShowsNoData() {
        let snapshot = SystemSnapshot(
            cpuTemperatureCelsius: nil,
            gpuTemperatureCelsius: 160,
            memoryPressureFraction: -0.4,
            memoryPressureLevel: .normal,
            thermalState: .nominal)

        let model = HealthModel.model(for: snapshot)

        XCTAssertNil(model.cpu.fillFraction)
        XCTAssertEqual(model.cpu.displayValue, "No data")
        XCTAssertEqual(model.gpu.fillFraction, 1)
        XCTAssertEqual(model.memory.fillFraction, 0)
    }

    func test_displayValuesAreRoundedWithUnits() {
        let snapshot = SystemSnapshot(
            cpuTemperatureCelsius: 64.6,
            gpuTemperatureCelsius: 58.2,
            memoryPressureFraction: 0.428,
            memoryPressureLevel: .normal,
            thermalState: .nominal)

        let model = HealthModel.model(for: snapshot)

        XCTAssertEqual(model.cpu.displayValue, "65 C")
        XCTAssertEqual(model.gpu.displayValue, "58 C")
        XCTAssertEqual(model.memory.displayValue, "43%")
    }
}
