import Foundation
import NucleicCore
import Testing

@testable import NucleicApp

@Suite("Transcript render length cache", .serialized)
struct TranscriptRenderLengthCacheTests {
    @Test func roundTripsAndReplacesAWidthSnapshot() async throws {
        let directory = FileManager.default.temporaryDirectory
            .appendingPathComponent(UUID().uuidString, isDirectory: true)
        defer { try? FileManager.default.removeItem(at: directory) }

        let sessionID = SessionID(rawValue: "length-round-trip")
        let context = TranscriptRenderLengthContext(
            contentWidth: 720, rowsPerSegment: 6,
            showDebugLines: false, showLockEvents: true, revertEpoch: 2)
        let segment = TranscriptRenderSegmentIdentity(
            lowerBound: 12, rowCount: 6,
            firstItemID: "seq-13", lastItemID: "assist-tail")
        var layout = TranscriptRenderLengthLayout(
            context: context, segments: [], updatedAt: .distantPast)
        layout.record(height: 318.5, for: segment, at: Date(timeIntervalSince1970: 1))

        let cache = TranscriptRenderLengthCache(directory: directory)
        await cache.save(layout, sessionID: sessionID)

        let reopened = TranscriptRenderLengthCache(directory: directory)
        let loaded = await reopened.load(sessionID: sessionID)
        #expect(loaded.count == 1)
        #expect(loaded.first?.height(for: segment) == 318.5)
        let lookup = TranscriptRenderLengthLookup(layouts: loaded)
        #expect(lookup.heights[context]?[segment] == 318.5)

        var replacement = layout
        replacement.record(height: 401, for: segment, at: Date(timeIntervalSince1970: 2))
        await reopened.save(replacement, sessionID: sessionID)
        let replaced = await reopened.load(sessionID: sessionID)
        #expect(replaced.count == 1)
        #expect(replaced.first?.height(for: segment) == 401)
    }

    @Test func compatibilityRequiresTheSameRenderingInputs() {
        let base = TranscriptRenderLengthContext(
            contentWidth: 700, rowsPerSegment: 6,
            showDebugLines: false, showLockEvents: true, revertEpoch: 1)
        let nearby = TranscriptRenderLengthContext(
            contentWidth: 716, rowsPerSegment: 6,
            showDebugLines: false, showLockEvents: true, revertEpoch: 1)
        let rewound = TranscriptRenderLengthContext(
            contentWidth: 700, rowsPerSegment: 6,
            showDebugLines: false, showLockEvents: true, revertEpoch: 2)

        #expect(base.isCompatible(with: nearby))
        #expect(!base.isCompatible(with: rewound))
    }
}
