//
//  SDLUDPCounter.swift
//  punchnet
//
//  Created by 安礼成 on 2026/5/6.
//

import Foundation

actor SDLUDPCounter {
    
    enum Direction {
        case inbound
        case outbound
    }
    
    class Metrics {
        var packetsNum: Int
        var bytesNum: Int
        
        init() {
            self.packetsNum = 0
            self.bytesNum = 0
        }
    }
    
    private var inboundCounters: [String: Metrics] = [:]
    private var outboundCounters: [String: Metrics] = [:]
    
    private var printTask: Task<Void, Never>?
    
    func start() {
        self.printTask = Task {
            while true {
                do {
                    try Task.checkCancellation()
                    try await Task.sleep(for: .seconds(1))
                    for (from, metric) in inboundCounters {
                        SDLLogger.log("[SDLUDPCounter] inbound from: \(from), packet: \(metric.packetsNum), bytes: \(metric.bytesNum)")
                    }
                    self.inboundCounters.removeAll()
                    
                    for (from, metric) in outboundCounters {
                        SDLLogger.log("[SDLUDPCounter] outbound from: \(from), packet: \(metric.packetsNum), bytes: \(metric.bytesNum)")
                    }
                    self.outboundCounters.removeAll()
                } catch {
                    break
                }
            }
        }
    }

    func increment(direction: Direction, from: String, bytes: Int) {
        switch direction {
        case .inbound:
            let metric = inboundCounters[from, default: .init()]
            metric.packetsNum += 1
            metric.bytesNum += bytes
            inboundCounters[from] = metric
        case .outbound:
            let metric = outboundCounters[from, default: .init()]
            metric.packetsNum += 1
            metric.bytesNum += bytes
            outboundCounters[from] = metric
        }
    }
    
    func stop() {
        self.printTask?.cancel()
        self.printTask = nil
    }
    
}
