import Foundation import XCTestDynamicOverlay import XXClient public struct MessengerSendFile { public typealias Callback = (Data, XXClient.Progress) -> Void public enum Error: Swift.Error, Equatable { case notConnected } public var run: (FileTransferSend.Params, @escaping Callback) throws -> Void public func callAsFunction( _ params: FileTransferSend.Params, callback: @escaping Callback ) throws -> Void { try run(params, callback) } } extension MessengerSendFile { public static func live(_ env: MessengerEnvironment) -> MessengerSendFile { MessengerSendFile { params, callback in guard let e2e = env.e2e() else { throw Error.notConnected } let fileTransfer = try env.initFileTransfer( params: InitFileTransfer.Params( e2eId: e2e.getId(), e2eFileTransferParamsJSON: env.getE2EFileTransferParams(), fileTransferParamsJSON: env.getFileTransferParams() ), callback: ReceiveFileCallback { _ in fatalError("Bindings issue: ReceiveFileCallback called when sending file.") } ) let semaphore = DispatchSemaphore(value: 0) var transferId: Data! var error: Swift.Error? transferId = try fileTransfer.send( params: params, callback: FileTransferProgressCallback { result in guard let transferId else { fatalError("Bindings issue: file transfer progress callback was called before send function returned transfer id.") } switch result { case .failure(let err): error = err semaphore.signal() case .success(let cb): callback(transferId, cb.progress) if cb.progress.completed || cb.progress.error != nil { semaphore.signal() } } } ) semaphore.wait() try fileTransfer.closeSend(transferId: transferId) if let error { throw error } } } } extension MessengerSendFile { public static let unimplemented = MessengerSendFile( run: XCTUnimplemented("\(Self.self)") ) }