package com.rosetta.messenger.network

import android.util.Log
import com.rosetta.messenger.network.connection.ConnectionEventRouter
import kotlinx.coroutines.CoroutineScope

internal class RuntimeRoutingAssembly(
    scope: CoroutineScope,
    tag: String,
    addLog: (String) -> Unit,
    handleInitializeAccount: (publicKey: String, privateKey: String) -> Unit,
    handleConnect: (reason: String) -> Unit,
    handleFastReconnect: (reason: String) -> Unit,
    handleDisconnect: (reason: String, clearCredentials: Boolean) -> Unit,
    handleAuthenticate: (publicKey: String, privateHash: String) -> Unit,
    handleProtocolStateChanged: (state: ProtocolState) -> Unit,
    handleSendPacket: (packet: Packet) -> Unit,
    handleSyncCompleted: (reason: String) -> Unit,
    handleOwnProfileResolved: (publicKey: String) -> Unit,
    handleOwnProfileFallbackTimeout: (sessionGeneration: Long) -> Unit
) {
    private val connectionEventRouter =
        ConnectionEventRouter(
            handleInitializeAccount = handleInitializeAccount,
            handleConnect = handleConnect,
            handleFastReconnect = handleFastReconnect,
            handleDisconnect = handleDisconnect,
            handleAuthenticate = handleAuthenticate,
            handleProtocolStateChanged = handleProtocolStateChanged,
            handleSendPacket = handleSendPacket,
            handleSyncCompleted = handleSyncCompleted,
            handleOwnProfileResolved = handleOwnProfileResolved,
            handleOwnProfileFallbackTimeout = handleOwnProfileFallbackTimeout
        )

    private val connectionSupervisor =
        ProtocolConnectionSupervisor(
            scope = scope,
            onEvent = { event -> connectionEventRouter.route(event) },
            onError = { error -> Log.e(tag, "ConnectionSupervisor event failed", error) },
            addLog = addLog
        )

    fun start() {
        connectionSupervisor.start()
    }

    fun post(event: ConnectionEvent) {
        connectionSupervisor.post(event)
    }
}
