// retoor import Foundation actor BotLogger { enum Level: String { case debug = "DEBUG" case info = "INFO" case warning = "WARN" case error = "ERROR" case spam = "SPAM" } private let dateFormatter: DateFormatter private let logFile: FileHandle? private let logToConsole: Bool private let minLevel: Level init(logPath: String? = nil, logToConsole: Bool = true, minLevel: Level = .info) { self.dateFormatter = DateFormatter() self.dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" self.logToConsole = logToConsole self.minLevel = minLevel if let path = logPath { _ = FileManager.default.createFile(atPath: path, contents: nil, attributes: nil) self.logFile = FileHandle(forWritingAtPath: path) self.logFile?.seekToEndOfFile() } else { self.logFile = nil } } deinit { try? logFile?.close() } func log(_ level: Level, _ message: String) { guard shouldLog(level) else { return } let timestamp = dateFormatter.string(from: Date()) let formattedMessage = "[\(timestamp)] [\(level.rawValue)] \(message)" if logToConsole { print(formattedMessage) } if let fileHandle = logFile, let data = (formattedMessage + "\n").data(using: .utf8) { try? fileHandle.write(contentsOf: data) } } func debug(_ message: String) { log(.debug, message) } func info(_ message: String) { log(.info, message) } func warning(_ message: String) { log(.warning, message) } func error(_ message: String) { log(.error, message) } func spam(_ message: String) { log(.spam, message) } private func shouldLog(_ level: Level) -> Bool { let levels: [Level] = [.debug, .info, .warning, .error, .spam] guard let currentIndex = levels.firstIndex(of: minLevel), let messageIndex = levels.firstIndex(of: level) else { return true } return messageIndex >= currentIndex } }