//
//  LKFTrace.swift
//  lkfc
//
//  Created by Alexander Holzer on 20.12.24.
//  Copyright © 2024 Alexander Holzer. All rights reserved.
//

import Foundation


public protocol LKFTraceReceiver : AnyObject {
    func trace (line: String, details: String?, aufenthalt: LKFAufenthalt?, context: LKFContext?)
}

public class LKFPrintTracer : LKFTraceReceiver {
    public func trace (line: String, details: String?, aufenthalt: LKFAufenthalt?, context: LKFContext?) {
        if let details {
            print ("\(line): \(details)")
        }
        else {
            print (line)
        }
    }
        
}

public actor LKFTraceManager {
    private var receivers: [LKFTraceReceiver]?
    
    public static var current = LKFTraceManager(receiver: LKFPrintTracer())
    
    public init (receiver: LKFTraceReceiver? = nil) {
        if let receiver {
            receivers = [receiver]
        }
    }
    
    public func trace (line: String, details: String? = nil, aufenthalt: LKFAufenthalt? = nil, context: LKFContext? = nil) {
        
        if let receivers {
            for r in receivers {
                r.trace (line: line, details: details, aufenthalt: aufenthalt, context: context)
            }
        }
    }
    
    public func add (receiver: LKFTraceReceiver) {
        if receivers != nil {
            receivers!.append (receiver)
        }
        else {
            receivers = [receiver]
        }
    }
    
    public func remove (receiver: LKFTraceReceiver) {
        if receivers != nil {
            receivers?.removeAll(where: { $0 === receiver })
        }
    }
    
    public var hasReceiver: Bool {
        guard let receivers else { return false }
        return receivers.count > 0
    }
    
    static public func trace (line: String, details: String? = nil, aufenthalt: LKFAufenthalt? = nil, context: LKFContext? = nil) {
        Task {
            await LKFTraceManager.current.trace (line: line, details: details, aufenthalt: aufenthalt, context: context)
        }
    }
}
