//
//  KMWebsocket.swift
//  PDF Reader Pro DMG
//
//  Created by wanjun on 2023/6/29.
//

import Cocoa
import Starscream

@objc protocol KMWebsocketDelegate {
    func websocketDidConnect()
    func websocketDidDisconnect()
    func websocketDidError(error: Error)
    func websocketDidReceive(content: String)
    func webSocketDidReceiveData(data: Data)
}

class KMWebsocket: NSObject {
    
    @objc weak var delegate: KMWebsocketDelegate?
    var newSocket: WebSocket!
    var isConnectedState = false

    @objc func connect(endPoint: String) {
        var request = URLRequest(url: URL(string: endPoint as String)!)
        request.timeoutInterval = 5
        newSocket = WebSocket(request: request)
        newSocket!.delegate = self
        newSocket!.connect()
    }
    
    func handleError(_ error: Error?) {
        if let e = error as? WSError {
            print("websocket encountered an error: \(e.message)")
        } else if let e = error {
            print("websocket encountered an error: \(e.localizedDescription)")
        } else {
            print("websocket encountered an error")
        }
    }
    
    @objc func disconnect() {
        newSocket?.disconnect()
    }
    
    @objc func isConnected()->Bool {
        return isConnectedState
    }
}

extension KMWebsocket: WebSocketDelegate {
    func didReceive(event: Starscream.WebSocketEvent, client: Starscream.WebSocketClient) {
        switch event {
        case .connected(let headers):
            isConnectedState = true
            self.delegate?.websocketDidConnect()
        case .disconnected(let reason, let code):
            isConnectedState = false
            self.delegate?.websocketDidDisconnect()
        case .text(let string):
            print("newSocket text=" + string)
            self.delegate?.websocketDidReceive(content: string)
        case .binary(let data):
            self.delegate?.webSocketDidReceiveData(data: data)
        case .ping(_):
            break
        case .pong(_):
            break
        case .viabilityChanged(_):
            break
        case .reconnectSuggested(_):
            break
        case .cancelled:
            isConnectedState = false
        case .error(let error):
            isConnectedState = false
            handleError(error)
        @unknown default:
            print(event)
        }
    }
}