import XCTest
@testable import SiliconPulseCore

final class MemoryPressureTests: XCTestCase {
    func test_pressureFractionUsesPressureSignalsRatherThanRawUsedMemory() {
        // Given high raw usage but plenty of inactive/free pages that can be reclaimed.
        let stats = MemoryPageStatistics(
            activePages: 700,
            wiredPages: 100,
            compressedPages: 20,
            inactivePages: 120,
            freePages: 55,
            speculativePages: 25,
            totalPages: 1_000)

        let fraction = MemoryPressureCalculator.pressureFraction(from: stats)

        // Then the estimate is below the raw used-memory ratio of 82%.
        XCTAssertLessThan(fraction, 0.55)
    }

    func test_pressureFractionRisesWithCompressionAndLowAvailableMemory() {
        let stats = MemoryPageStatistics(
            activePages: 620,
            wiredPages: 220,
            compressedPages: 160,
            inactivePages: 10,
            freePages: 5,
            speculativePages: 0,
            totalPages: 1_000)

        let fraction = MemoryPressureCalculator.pressureFraction(from: stats)

        XCTAssertGreaterThan(fraction, 0.75)
    }

    func test_pressureFractionClampsToZeroThroughOne() {
        XCTAssertEqual(
            MemoryPressureCalculator.pressureFraction(from: MemoryPageStatistics(
                activePages: -10,
                wiredPages: 0,
                compressedPages: 0,
                inactivePages: 100,
                freePages: 100,
                speculativePages: 0,
                totalPages: 100)),
            0)

        XCTAssertEqual(
            MemoryPressureCalculator.pressureFraction(from: MemoryPageStatistics(
                activePages: 800,
                wiredPages: 500,
                compressedPages: 300,
                inactivePages: 0,
                freePages: 0,
                speculativePages: 0,
                totalPages: 1_000)),
            1)
    }

    func test_kernelPressureValuesMapToSemanticLevels() {
        XCTAssertEqual(MemoryPressureLevel(kernelValue: 1), .normal)
        XCTAssertEqual(MemoryPressureLevel(kernelValue: 2), .warning)
        XCTAssertEqual(MemoryPressureLevel(kernelValue: 4), .critical)
        XCTAssertEqual(MemoryPressureLevel(kernelValue: 99), .normal)
    }
}
