import Foundation
import Testing

@testable import NucleicProtocol

/// Pins the relay routing envelope to the Room DO (`cloud/nucleic-edge/src/room.ts`): the device
/// tag and the wrap/unwrap framing must match byte-for-byte, or the host and relay disagree on
/// which peer a frame belongs to.
@Suite struct RelayEnvelopeTests {
    private func hex(_ d: Data) -> String { d.map { String(format: "%02x", $0) }.joined() }

    @Test func deviceTagMatchesTheRoomDO() {
        // Vector from room.ts deviceTag("phone-A") = sha256("phone-A").slice(0,8).
        #expect(hex(RelayEnvelope.tag(forDeviceID: "phone-A")) == "532eeba88f66c834")
        #expect(RelayEnvelope.tag(forDeviceID: "phone-A").count == RelayEnvelope.tagLength)
    }

    @Test func wrapProducesVersionTagPayload() {
        let tag = RelayEnvelope.tag(forDeviceID: "phone-A")
        let framed = RelayEnvelope.wrap(Data([1, 2, 3, 4]), tag: tag)
        #expect(framed.first == RelayEnvelope.version)
        #expect(framed.count == RelayEnvelope.headerLength + 4)
        #expect(framed.suffix(4) == Data([1, 2, 3, 4]))
        #expect(framed.subdata(in: 1..<9) == tag)
    }

    @Test func wrapUnwrapRoundTrips() {
        let tag = RelayEnvelope.tag(forDeviceID: "host-dev")
        let frame = Data((0..<200).map { UInt8($0 % 251) })
        let parsed = RelayEnvelope.unwrap(RelayEnvelope.wrap(frame, tag: tag))
        #expect(parsed?.tag == tag)
        #expect(parsed?.frame == frame)
    }

    @Test func unwrapRejectsMalformedEnvelopes() {
        #expect(RelayEnvelope.unwrap(Data()) == nil)
        #expect(RelayEnvelope.unwrap(Data([0x01, 1, 2])) == nil) // too short for a full tag
        #expect(RelayEnvelope.unwrap(Data([0x02] + Array(repeating: 0, count: 12))) == nil) // wrong version
    }

    @Test func emptyPayloadIsValid() {
        let tag = RelayEnvelope.tag(forDeviceID: "x")
        let parsed = RelayEnvelope.unwrap(RelayEnvelope.wrap(Data(), tag: tag))
        #expect(parsed?.frame == Data())
        #expect(parsed?.tag == tag)
    }
}
