import Foundation
import Testing
@testable import IrdP2P
@testable import IrdP2PSignaling
import IrdP2PCrypto
/// Against the SDK's own live app. Set `IRD_P2P_HOST` (the app hostname) and
/// `IRD_P2P_ORIGIN` (an origin its allowlist admits) to enable.
@Suite(.enabled(if: LiveEnv.host != nil), .serialized) struct LiveSmokeTests {
@Test func descriptorJoinPingAndTurn() async throws {
let app = P2PApp(host: LiveEnv.host!, appSalt: "ird-swift-live/v1", origin: LiveEnv.origin)
let d = await app.descriptor()
#expect(!d.isFallback)
#expect(d.version == "1" && d.protocolName == "ap2p-signal")
#expect(d.endpoints.ws.absoluteString == "wss://\(LiveEnv.host!)/ws")
let ice = await app.iceConfiguration()
#expect(!ice.servers.isEmpty) // TURN credentials minted with the configured Origin
#expect(ice.servers.first?.urls.contains { $0.hasPrefix("turn:") } == true)
var opts = RoomOptions()
opts.preferDataChannel = false
let secret = RoomSecret.random()
let a = try await app.join(secret: secret, peerId: lowPeer, options: opts)
let ca = Collector(a)
#expect(await ca.waitFor(.status(.joined), timeout: .seconds(10)))
let b = try await app.join(secret: secret, peerId: highPeer, options: opts)
let cb = Collector(b)
#expect(await ca.waitFor(.peerReady(highPeer, .relayed), timeout: .seconds(10)))
#expect(await cb.waitFor(.peerReady(lowPeer, .relayed), timeout: .seconds(10)))
try await a.send(to: highPeer, .json(.string("live")))
#expect(await cb.waitFor(.message(from: lowPeer, .json(.string("live"))), timeout: .seconds(10)))
await b.leave()
#expect(await ca.waitFor(.peerLeft(highPeer), timeout: .seconds(10)))
await a.leave()
}
@Test func directDataChannelOverTheInternet() async throws {
let app = P2PApp(host: LiveEnv.host!, appSalt: "ird-swift-live/v1", origin: LiveEnv.origin)
let secret = RoomSecret.random()
let a = try await app.join(secret: secret, peerId: lowPeer)
let ca = Collector(a)
let b = try await app.join(secret: secret, peerId: highPeer)
let cb = Collector(b)
#expect(await ca.waitFor(.peerReady(highPeer, .direct), timeout: .seconds(30)))
#expect(await cb.waitFor(.peerReady(lowPeer, .direct), timeout: .seconds(30)))
let big = Data((0..<50_000).map { UInt8($0 % 253) })
try await a.send(to: highPeer, .data(big))
#expect(await cb.waitFor(.message(from: lowPeer, .data(big)), timeout: .seconds(20)))
await a.leave(); await b.leave()
}
@Test func mailboxRoundTrip() async throws {
let app = P2PApp(host: LiveEnv.host!, appSalt: "ird-swift-live/v1", origin: LiveEnv.origin)
let d = await app.descriptor()
try #require(d.mailbox != nil)
let mbx = try await app.mailbox(secret: .random())
let r = try await mbx.deposit(.json(.string("offline")))
#expect(!r.deduped)
let all = try await mbx.replayAll(after: nil)
#expect(all.items.map(\.message) == [.json(.string("offline"))])
}
}
enum LiveEnv {
static var host: String? { ProcessInfo.processInfo.environment["IRD_P2P_HOST"].flatMap { $0.isEmpty ? nil : $0 } }
static var origin: String? { ProcessInfo.processInfo.environment["IRD_P2P_ORIGIN"].flatMap { $0.isEmpty ? nil : $0 } }
}