package com.rosetta.messenger.network

import com.rosetta.messenger.network.connection.CallSignalBridge
import com.rosetta.messenger.network.connection.OutgoingMessagePipelineService
import com.rosetta.messenger.network.connection.PacketSubscriptionFacade
import kotlinx.coroutines.flow.SharedFlow

class RuntimePacketIoFacade(
    private val postConnectionEvent: (ConnectionEvent) -> Unit,
    private val outgoingMessagePipelineServiceProvider: () -> OutgoingMessagePipelineService,
    private val callSignalBridge: CallSignalBridge,
    private val packetSubscriptionFacade: PacketSubscriptionFacade
) {
    fun send(packet: Packet) {
        postConnectionEvent(ConnectionEvent.SendPacket(packet))
    }

    fun sendMessageWithRetry(packet: PacketMessage) {
        outgoingMessagePipelineServiceProvider().sendWithRetry(packet)
    }

    fun resolveOutgoingRetry(messageId: String) {
        outgoingMessagePipelineServiceProvider().resolveOutgoingRetry(messageId)
    }

    fun clearOutgoingRetries() {
        outgoingMessagePipelineServiceProvider().clearRetryQueue()
    }

    fun sendPacket(packet: Packet) {
        send(packet)
    }

    fun sendCallSignal(
        signalType: SignalType,
        src: String = "",
        dst: String = "",
        sharedPublic: String = "",
        callId: String = "",
        joinToken: String = ""
    ) {
        callSignalBridge.sendCallSignal(signalType, src, dst, sharedPublic, callId, joinToken)
    }

    fun sendWebRtcSignal(signalType: WebRTCSignalType, sdpOrCandidate: String) {
        callSignalBridge.sendWebRtcSignal(signalType, sdpOrCandidate)
    }

    fun requestIceServers() {
        callSignalBridge.requestIceServers()
    }

    fun waitCallSignal(callback: (PacketSignalPeer) -> Unit): (Packet) -> Unit {
        return callSignalBridge.waitCallSignal(callback)
    }

    fun unwaitCallSignal(callback: (Packet) -> Unit) {
        callSignalBridge.unwaitCallSignal(callback)
    }

    fun waitWebRtcSignal(callback: (PacketWebRTC) -> Unit): (Packet) -> Unit {
        return callSignalBridge.waitWebRtcSignal(callback)
    }

    fun unwaitWebRtcSignal(callback: (Packet) -> Unit) {
        callSignalBridge.unwaitWebRtcSignal(callback)
    }

    fun waitIceServers(callback: (PacketIceServers) -> Unit): (Packet) -> Unit {
        return callSignalBridge.waitIceServers(callback)
    }

    fun unwaitIceServers(callback: (Packet) -> Unit) {
        callSignalBridge.unwaitIceServers(callback)
    }

    fun waitPacket(packetId: Int, callback: (Packet) -> Unit) {
        packetSubscriptionFacade.waitPacket(packetId, callback)
    }

    fun unwaitPacket(packetId: Int, callback: (Packet) -> Unit) {
        packetSubscriptionFacade.unwaitPacket(packetId, callback)
    }

    fun packetFlow(packetId: Int): SharedFlow<Packet> {
        return packetSubscriptionFacade.packetFlow(packetId)
    }
}
