//
//  SDLUDPHoleServiceProxy.swift
//  punchnet
//
//  Created by 安礼成 on 2026/5/21.
//
import Foundation
import NIOCore

actor SDLUDPHoleServiceProxy {
    typealias ControlEventHandler = @Sendable (SDLUDPHoleService.Event) async -> Void

    private var udpHoleService: SDLUDPHoleService?
    private var generation: UInt64 = 0

    func makeEventHandler(onControlEvent: @escaping ControlEventHandler) -> SDLUDPHoleService.EventHandler {
        self.generation &+= 1
        let generation = self.generation

        return { [weak self] event in
            await self?.handleEvent(event, generation: generation, onControlEvent: onControlEvent)
        }
    }

    func replace(_ udpHoleService: SDLUDPHoleService?) async {
        let oldUDPHoleService = self.udpHoleService
        self.udpHoleService = udpHoleService

        if oldUDPHoleService !== udpHoleService {
            await oldUDPHoleService?.stop()
        }
    }

    func stop() async {
        self.generation &+= 1

        let udpHoleService = self.udpHoleService
        self.udpHoleService = nil

        await udpHoleService?.stop()
    }

    func send(type: SDLPacketType, data: Data, remoteAddress: SocketAddress) async {
        await self.udpHoleService?.send(type: type, data: data, remoteAddress: remoteAddress)
    }

    private func handleEvent(_ event: SDLUDPHoleService.Event, generation: UInt64, onControlEvent: ControlEventHandler) async {
        guard generation == self.generation else {
            return
        }

        await onControlEvent(event)
    }
}
