//
// ReplayTests.swift — T-iOS-16 测试 3：>1 MiB 单帧回放（吸收 spike③ + 对抗变体）
//
// ring-buffer 回放是单帧全量（src/session/session.ts attachWs → buffer.snapshot()），
// JSON 会把控制字节 \uXXXX 转义膨胀 1-6×（src/protocol.ts:186）：
//   - 复现分支：平台默认 maximumMessageSize=1 MiB 收不下（withKnownIssue 常驻记录，
//     若"意外通过"说明平台行为变了，须重新评估 Tunables.maxWSMessageBytes）
//   - 修复分支：Tunables.maxWSMessageBytes（16 MiB）→ 回放完整
//   - 对抗变体：ESC/C0 密集输出（转义膨胀 ~6×）→ 仍完整

import Foundation
import Testing
import WireProtocol

@Suite("T-iOS-16 回放上限(真服务器)", .serialized, .timeLimit(.minutes(5)))
struct ReplayTests {

    @Test(">1MiB 单帧回放 — 默认 1MiB 上限复现失败(known issue);Tunables 16MiB 成功")
    func replayOver1MiBFailsAtDefaultLimitAndSucceedsAt16MiB() async throws {
        let server = try await ServerHarness.shared.server()

        // 造数据:attach(null) 后灌 >1MiB 普通输出,再 detach(PTY/ring 存活)。
        let generator = WSTestClient(server: server, origin: server.origin)
        let sessionId = try await attachAndAwaitAttached(client: generator, sessionId: nil)
        try await generator.send(shellCommand(
            "perl -e 'print \"a\" x \(HarnessTunables.bulkOutputBytes)'"))
        let produced = try await accumulateOutputBytes(
            client: generator, minBytes: HarnessTunables.bulkOutputBytes)
        #expect(produced >= HarnessTunables.bulkOutputBytes)
        generator.close()

        // 复现分支:平台默认 maximumMessageSize(1 MiB) → 回放必失败。
        let defaultClient = WSTestClient(server: server, origin: server.origin, maxMessageBytes: nil)
        let defaultResult = await replayResult(
            client: defaultClient, sessionId: sessionId, minBytes: HarnessTunables.bulkOutputBytes)
        defaultClient.close()
        if case .failure(let error) = defaultResult {
            #expect(isMessageTooLongError(error),
                    "失败模式应为 NSPOSIXErrorDomain EMSGSIZE(40)/ENOBUFS(55),实际 \(describeError(error))")
        }
        withKnownIssue("默认 maximumMessageSize=1MiB 收不下 >1MiB 单帧 ring-buffer 回放 — 平台限制,修法即 Tunables.maxWSMessageBytes=16MiB(若此处'意外通过',说明平台行为变了,须重新评估)") {
            _ = try defaultResult.get()
        }

        // 修复分支:16 MiB → 全量回放成功,attached 采用同一 sessionId。
        let bigClient = WSTestClient(server: server, origin: server.origin)
        let summary = try await replayResult(
            client: bigClient, sessionId: sessionId, minBytes: HarnessTunables.bulkOutputBytes).get()
        #expect(summary.adoptedSessionId == sessionId)
        #expect(summary.totalOutputBytes >= HarnessTunables.bulkOutputBytes)
        bigClient.close()
        await killSessionBestEffort(server: server, id: sessionId)
    }

    @Test("对抗: ESC/C0 密集输出(JSON 转义膨胀~6×)回放,16MiB 仍完整")
    func escDenseReplayStillSucceedsAt16MiB() async throws {
        let server = try await ServerHarness.shared.server()

        let generator = WSTestClient(server: server, origin: server.origin)
        let sessionId = try await attachAndAwaitAttached(client: generator, sessionId: nil)
        // perl 的 \e = ESC(0x1B):每 4 原始字节 JSON 转义成 9 字节("[0m")。
        try await generator.send(shellCommand(
            "perl -e 'print \"\\e[0m\" x \(HarnessTunables.escSequenceRepeats)'"))
        let produced = try await accumulateOutputBytes(
            client: generator, minBytes: HarnessTunables.escSequenceRawBytes)
        #expect(produced >= HarnessTunables.escSequenceRawBytes)
        generator.close()

        let bigClient = WSTestClient(server: server, origin: server.origin)
        let summary = try await replayResult(
            client: bigClient, sessionId: sessionId,
            minBytes: HarnessTunables.escSequenceRawBytes).get()
        #expect(summary.adoptedSessionId == sessionId)
        #expect(summary.totalOutputBytes >= HarnessTunables.escSequenceRawBytes)
        #expect(summary.containsSoftReset, "回放应含 ESC[0m(转义序列在回放中原样保留)")
        bigClient.close()
        await killSessionBestEffort(server: server, id: sessionId)
    }
}
