//
//  SDLConfiguration.swift
//  sdlan
//
//  Created by 安礼成 on 2025/7/14.
//
import Foundation
import NIOCore

// 配置项目
public class SDLConfiguration {
    public struct NetworkAddress {
        public let networkId: UInt32
        public let ip: UInt32
        public let maskLen: UInt8
        public let mac: Data
        public let networkDomain: String
        
        // ip地址
        var ipAddress: String {
            return SDLUtil.int32ToIp(self.ip)
        }
        
        // 掩码
        var maskAddress: String {
            let len0 = 32 - maskLen
            let num: UInt32 = (0xFFFFFFFF >> len0) << len0
            
            return SDLUtil.int32ToIp(num)
        }
        
        // 网络地址
        var netAddress: String {
            let len0 = 32 - maskLen
            let mask: UInt32 = (0xFFFFFFFF >> len0) << len0
            
            return SDLUtil.int32ToIp(self.ip & mask)
        }
    }
    
    // 当前的客户端版本
    let version: Int
    
    let serverIp: String
    let stunServers: [String]
    
    let noticePort: Int
    
    lazy var stunSocketAddress: SocketAddress = {
        let stunServer = stunServers[0]
        return try! SocketAddress.makeAddressResolvingHost(stunServer, port: 1365)
    }()
    
    // 网络探测地址信息
    lazy var stunProbeSocketAddressArray: [[SocketAddress]] = {
        return stunServers.map { stunServer in
            [
                try! SocketAddress.makeAddressResolvingHost(stunServer, port: 1365),
                try! SocketAddress.makeAddressResolvingHost(stunServer, port: 1366)
            ]
        }
    }()
    
    let clientId: String
    let networkAddress: NetworkAddress
    let hostname: String
    let accessToken: String
    let identityId: UInt32

    public init(version: Int,
                serverIp: String,
                stunServers: [String],
                clientId: String,
                networkAddress: NetworkAddress,
                hostname: String,
                noticePort: Int,
                accessToken: String,
                identityId: UInt32) {
        
        self.version = version
        self.serverIp = serverIp
        self.stunServers = stunServers
        self.clientId = clientId
        self.networkAddress = networkAddress
        self.noticePort = noticePort
        self.accessToken = accessToken
        self.identityId = identityId
        self.hostname = hostname
    }
}

// 解析配置文件
extension SDLConfiguration {
    
    static func parse(options: [String: NSObject]) -> SDLConfiguration? {
        guard let version = options["version"] as? Int,
              let serverIp = options["server_ip"] as? String,
              let stunAssistIp = options["stun_assist_ip"] as? String,
              let noticePort = options["notice_port"] as? Int,
              let accessToken = options["access_token"] as? String,
              let identityId = options["identity_id"] as? UInt32,
              let clientId = options["client_id"] as? String,
              let hostname = options["hostname"] as? String,
              let networkAddressDict = options["network_address"] as? [String: NSObject] else {
            return nil
        }
        
        guard let networkAddress = parseNetworkAddress(networkAddressDict) else {
            return nil
        }
        
        let stunServers: [String] = [
            serverIp,
            stunAssistIp
        ]
        
        return SDLConfiguration(version: version,
                                serverIp: serverIp,
                                stunServers: stunServers,
                                clientId: clientId,
                                networkAddress: networkAddress,
                                hostname: hostname,
                                noticePort: noticePort,
                                accessToken: accessToken,
                                identityId: identityId)
    }
    
    private static func parseNetworkAddress(_ config: [String: NSObject]) -> SDLConfiguration.NetworkAddress? {
        guard let networkId = config["network_id"] as? UInt32,
              let ipStr = config["ip"] as? String,
              let ip = SDLUtil.ipv4StrToInt32(ipStr),
              let maskLen = config["mask_len"] as? UInt8,
              let mac = config["mac"] as? Data,
              let networkDomain = config["network_domain"] as? String else {
            return nil
        }
        
        return .init(networkId: networkId, ip: ip, maskLen: maskLen, mac: mac, networkDomain: networkDomain)
    }
    
}
