//
//  SDLPacketType.swift
//  Tun
//
//  Created by 安礼成 on 2024/4/10.
//

import Foundation
import NIOCore

// 消息类型定义
enum SDLPacketType: UInt8 {
    case empty = 0x00
    
    case registerSuper = 0x01
    case registerSuperAck = 0x02
    case registerSuperNak = 0x04
    
    case unregisterSuper = 0x05
    
    case queryInfo = 0x06
    case peerInfo = 0x07
    
    // 心跳机制
    case ping = 0x08
    case pong = 0x09
    
    // 事件类型
    case event = 0x10
    
    case register = 0x20
    case registerAck = 0x21
    
    case stunRequest = 0x30
    case stunReply = 0x31

    case stunProbe = 0x32
    case stunProbeReply = 0x33
    
    // arp查询
    case arpRequest = 0x50
    case arpResponse = 0x51
    
    // 权限控制
    case policyRequest = 0xb0
    case policyResponse = 0xb1
    
    // 获取欢迎消息
    case welcome = 0x4F
    
    case data = 0xFF
}

// Id生成器
struct SDLIdGenerator: Sendable {
    // 消息体id
    private var packetId: UInt32
    
    init(seed packetId: UInt32) {
        self.packetId = packetId
    }
    
    mutating func nextId() -> UInt32 {
        let packetId = self.packetId
        self.packetId = packetId + 1
        return packetId
    }
}

// 定义事件类型

// --MARK: 网络类型探测
// 探测的Attr属性
enum SDLProbeAttr: UInt8 {
    case none = 0
    case port = 1
    case peer = 2
}

// Nak的错误类型，不同的错误客户端的处理逻辑不一样
enum SDLNAKErrorCode: UInt8 {
    case invalidToken = 1
    case nodeDisabled = 2
    case noIpAddress = 3
    case networkFault = 4
    case internalFault = 5
}

extension SDLV4Info {
    func socketAddress() async throws -> SocketAddress? {
        guard self.v4.count == 4 else {
            return nil
        }
        
        let address = "\(v4[0]).\(v4[1]).\(v4[2]).\(v4[3])"
        return try SocketAddress(ipAddress: address, port: Int(port))
    }
}

extension SDLV6Info {
    func socketAddress() async throws -> SocketAddress? {
        guard let address = SDLUtil.ipv6DataToString(self.v6) else {
            return nil
        }
        
        return try SocketAddress(ipAddress: address, port: Int(port))
    }
}

extension SDLData {
    
    func format() -> String {
        return "network_id: \(self.networkID), src_mac: \(LayerPacket.MacAddress.description(data: self.srcMac)), dst_mac: \(LayerPacket.MacAddress.description(data: self.dstMac)), data: \([UInt8](self.data))"
    }
    
}

extension SDLStunProbeReply {
    func socketAddress() async -> SocketAddress? {
        let address = SDLUtil.int32ToIp(self.ip)
        
        return try? SocketAddress(ipAddress: address, port: Int(port))
    }
}


enum SDLQUICInboundMessage {
    // 欢迎消息
    case welcome(SDLWelcome)
    
    case pong
    
    // 注册相关
    case registerSuperAck(SDLRegisterSuperAck)
    case registerSuperNak(SDLRegisterSuperNak)
    
    case peerInfo(SDLPeerInfo)
    case event(SDLEvent)
    case policyReponse(SDLPolicyResponse)
    
    case arpResponse(SDLArpResponse)
}

// 命令类型
enum SDLEventType: UInt8 {
    case natChanged = 0x03
    case sendRegister = 0x04
    case networkShutdown = 0xFF
}
