//
//  SDLHoleMessageDecoder.swift
//  punchnet
//
//  Created by 安礼成 on 2026/4/15.
//
import Foundation
import NIOCore
import NIOFoundationCompat
import NIOPosix
import SwiftProtobuf

// --MARK: 进来的消息, 这里需要采用代数类型来表示
enum SDLHoleMessage {
    case data(SDLData)
    case control(SDLHoleControlMessage)
}

enum SDLHoleControlMessage {
    case register(SDLRegister)
    case registerAck(SDLRegisterAck)
    case stunProbeReply(SDLStunProbeReply)
    case stunReply(SDLStunReply)
}

extension SDLHoleMessage {
    
    static func decode(buffer: inout ByteBuffer) throws -> SDLHoleMessage? {
        guard let type = buffer.readInteger(as: UInt8.self),
              let packetType = SDLPacketType(rawValue: type) else {
            return nil
        }
        
        switch packetType {
        case .data:
            guard let bytes = buffer.readData(length: buffer.readableBytes, byteTransferStrategy: .copy),
                  let dataPacket = try? SDLData(serializedBytes: bytes) else {
                return nil
            }
            return .data(dataPacket)
        case .register:
            guard let bytes = buffer.readData(length: buffer.readableBytes, byteTransferStrategy: .copy),
               let registerPacket = try? SDLRegister(serializedBytes: bytes) else {
                return nil
            }
            return .control(.register(registerPacket))
        case .registerAck:
            guard let bytes = buffer.readData(length: buffer.readableBytes, byteTransferStrategy: .copy),
               let registerAck = try? SDLRegisterAck(serializedBytes: bytes) else {
                return nil
            }
            return .control(.registerAck(registerAck))
        case .stunProbeReply:
            guard let bytes = buffer.readData(length: buffer.readableBytes, byteTransferStrategy: .copy),
               let stunProbeReply = try? SDLStunProbeReply(serializedBytes: bytes) else {
                return nil
            }
            return .control(.stunProbeReply(stunProbeReply))
        case .stunReply:
            guard let bytes = buffer.readData(length: buffer.readableBytes, byteTransferStrategy: .copy),
               let stunReply = try? SDLStunReply(serializedBytes: bytes) else {
                return nil
            }
            return .control(.stunReply(stunReply))
        default:
            SDLLogger.log("[SDLUDPHole] decode miss type: \(type)", for: .debug)
            
            return nil
        }
    }
    
}
