import UIKit

@MainActor
final class SybilBackgroundTaskAssertion {
    private let name: String
    private var identifier: UIBackgroundTaskIdentifier = .invalid

    init?(name: String, onExpiration: @escaping @MainActor () -> Void = {}) {
        self.name = name
        identifier = UIApplication.shared.beginBackgroundTask(withName: name) { [weak self] in
            Task { @MainActor in
                guard let self else { return }
                SybilLog.warning(SybilLog.app, "Background task expired: \(self.name)")
                onExpiration()
                self.end()
            }
        }

        guard identifier != .invalid else {
            SybilLog.warning(SybilLog.app, "Failed to acquire background task: \(name)")
            return nil
        }

        SybilLog.debug(SybilLog.app, "Acquired background task: \(name)")
    }

    func end() {
        guard identifier != .invalid else {
            return
        }

        UIApplication.shared.endBackgroundTask(identifier)
        identifier = .invalid
        SybilLog.debug(SybilLog.app, "Ended background task: \(name)")
    }
}
