// // DebugLogger.swift // AppClientBaseSwift // // Debug logging utilities // Tiện ích ghi log debug // import Foundation // MARK: - Debug Logger // Logger Debug /// Debug logging utility /// Tiện ích ghi log debug enum DebugLogger { /// Log level /// Mức độ log enum Level: String { case verbose = "📝" case info = "ℹ️" case warning = "⚠️" case error = "❌" case success = "✅" } /// Log message with level /// Ghi log message với level /// - Parameters: /// - level: Log level / Mức độ log /// - message: Log message / Thông điệp log /// - file: Source file / File nguồn /// - function: Function name / Tên function /// - line: Line number / Số dòng static func log( _ level: Level, _ message: String, file: String = #file, function: String = #function, line: Int = #line ) { #if DEBUG let fileName = (file as NSString).lastPathComponent let timestamp = DateFormatter.localizedString(from: Date(), dateStyle: .none, timeStyle: .medium) print("\(level.rawValue) [\(timestamp)] \(fileName):\(line) - \(function)") print(" \(message)") #endif } /// Log verbose message /// Ghi log verbose static func verbose(_ message: String, file: String = #file, function: String = #function, line: Int = #line) { log(.verbose, message, file: file, function: function, line: line) } /// Log info message /// Ghi log info static func info(_ message: String, file: String = #file, function: String = #function, line: Int = #line) { log(.info, message, file: file, function: function, line: line) } /// Log warning message /// Ghi log warning static func warning(_ message: String, file: String = #file, function: String = #function, line: Int = #line) { log(.warning, message, file: file, function: function, line: line) } /// Log error message /// Ghi log error static func error(_ message: String, file: String = #file, function: String = #function, line: Int = #line) { log(.error, message, file: file, function: function, line: line) } /// Log success message /// Ghi log success static func success(_ message: String, file: String = #file, function: String = #function, line: Int = #line) { log(.success, message, file: file, function: function, line: line) } /// Log JSON data /// Ghi log dữ liệu JSON /// - Parameters: /// - data: JSON data / Dữ liệu JSON /// - title: Optional title / Tiêu đề tùy chọn static func logJSON(_ data: Data, title: String = "JSON Response") { #if DEBUG guard let jsonString = String(data: data, encoding: .utf8) else { error("Unable to convert data to string") return } // Try to pretty print JSON // Thử format JSON đẹp if let jsonData = jsonString.data(using: .utf8), let jsonObject = try? JSONSerialization.jsonObject(with: jsonData), let prettyData = try? JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted), let prettyString = String(data: prettyData, encoding: .utf8) { print("📄 \(title):") print(prettyString) } else { print("📄 \(title):") print(jsonString) } #endif } /// Log API request /// Ghi log API request /// - Parameters: /// - method: HTTP method / Phương thức HTTP /// - url: Request URL / URL request /// - headers: Request headers / Headers request /// - body: Request body / Body request static func logRequest( method: String, url: String, headers: [String: String]? = nil, body: Data? = nil ) { #if DEBUG print("🚀 API Request:") print(" Method: \(method)") print(" URL: \(url)") if let headers = headers, !headers.isEmpty { print(" Headers:") headers.forEach { key, value in // Hide sensitive data // Ẩn dữ liệu nhạy cảm if key.lowercased() == "authorization" { print(" \(key): Bearer ***") } else { print(" \(key): \(value)") } } } if let body = body { print(" Body:") logJSON(body, title: "Request Body") } #endif } /// Log API response /// Ghi log API response /// - Parameters: /// - statusCode: HTTP status code / Mã trạng thái HTTP /// - data: Response data / Dữ liệu response /// - error: Error if any / Lỗi nếu có static func logResponse( statusCode: Int, data: Data?, error: Error? = nil ) { #if DEBUG if let error = error { print("❌ API Response Error:") print(" Status Code: \(statusCode)") print(" Error: \(error.localizedDescription)") } else { let emoji = statusCode >= 200 && statusCode < 300 ? "✅" : "⚠️" print("\(emoji) API Response:") print(" Status Code: \(statusCode)") } if let data = data { logJSON(data, title: "Response Data") } #endif } }