//
//  PacketTunnelProvider.swift
//  punchnet
//
//  Created by 安礼成 on 2025/8/3.
//

import NetworkExtension

enum TunnelError: Error {
    case invalidConfiguration
    case invalidContext
}

class PacketTunnelProvider: NEPacketTunnelProvider {
    var contextActor: SDLContextActor?
    private var rootTask: Task<Void, Error>?
    
    override func startTunnel(options: [String: NSObject]?, completionHandler: @escaping (Error?) -> Void) {
        // host: "192.168.0.101", port: 1265
        guard let options, let config = SDLConfiguration.parse(options: options) else {
            completionHandler(TunnelError.invalidConfiguration)
            return
        }
        
        // 如果当前在运行状态，不允许重复请求
        guard self.contextActor == nil else {
            completionHandler(TunnelError.invalidContext)
            return
        }
        
        // 加密算法
        let rsaCipher = try! CCRSACipher(keySize: 1024)
        self.rootTask = Task {
            self.contextActor = SDLContextActor(provider: self, config: config, rsaCipher: rsaCipher)
            await self.contextActor?.start()
            completionHandler(nil)
        }
    }
    
    override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
        // Add code here to start the process of stopping the tunnel.
        Task {
            await self.contextActor?.stop()
            self.contextActor = nil
            
            self.rootTask?.cancel()
            self.rootTask = nil
            
            completionHandler()
        }
    }
    
    override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) {
        // Add code here to handle the message.
        if let handler = completionHandler {
            handler(messageData)
        }
    }
    
    override func sleep(completionHandler: @escaping () -> Void) {
        // Add code here to get ready to sleep.
        completionHandler()
    }
    
    override func wake() {
        // Add code here to wake up.
    }
    
}

// 获取物理网卡ip地址
extension PacketTunnelProvider {
    
    public static var viaInterface: NetworkInterface? = {
        let interfaces = NetworkInterfaceManager.getInterfaces()
        
        return interfaces.first {$0.name == "en0"}
    }()
}
