import Dependencies
import Foundation
/// It's intuitive to be able to initialize `os.Logger` with just an `import Utilities` call
@_exported import os.log

public extension os.Logger {
    init(category: String) {
        let subsystem = Bundle.main.bundleIdentifier ?? "ai.suno.ios"
        self = Logger(subsystem: subsystem, category: category)
    }

    /// Namespaced for telemetry calls
    /// Computed property because extensions can't have stored properties and this struct init is essentially free
    var telemetry: Telemetry {
        Telemetry(logger: self)
    }

    /// Namespaced for telemetry calls
    struct Telemetry {
        private let logger: os.Logger

        public init(logger: os.Logger) {
            self.logger = logger
        }

        private enum LoggerError: Error {
            case assertionFailure
        }

        /// Error sent to telemetry
        public func error(_ error: Error, message: String? = nil) {
            if let message {
                logger.error("\(message): \(error)")
            } else {
                logger.error("\(error)")
            }

            @Dependency(\.telemetryClient) var telemetry
            telemetry.record(error: error, message: message)
        }

        /// Assertion failure (something shouldn't have happened) sent to telemetry
        /// Calls `os.Logger.error` under-the-hood, but has a generic error that allows us to pass in just-a-message.
        public func assertionFailure(_ message: String) {
            logger.error("Assertion failure: \(message)")

            @Dependency(\.telemetryClient) var telemetry
            telemetry.record(error: LoggerError.assertionFailure, message: message)
        }
    }
}
