import Foundation import HAKit import Shared class NotificationManagerLocalPushInterfaceDirect: NotificationManagerLocalPushInterface { func status(for server: Server) -> NotificationManagerLocalPushStatus { .allowed(localPushManagers[server].state) } private var localPushManagers: PerServerContainer! weak var localPushDelegate: LocalPushManagerDelegate? init(delegate: LocalPushManagerDelegate) { self.localPushDelegate = delegate self.localPushManagers = .init { [weak self] server in let manager = LocalPushManager(server: server) let token = NotificationCenter.default.addObserver( forName: LocalPushManager.stateDidChange, object: manager, queue: .main, using: { [weak self] _ in self?.pushManagerStateDidChange(server: server) } ) return .init(manager) { _, _ in NotificationCenter.default.removeObserver(token) } } } func addObserver( for server: Server, handler: @escaping (NotificationManagerLocalPushStatus) -> Void ) -> HACancellable { let observer = Observer(identifier: UUID(), server: server, handler: handler) observers.append(observer) return HABlockCancellable { [weak self] in self?.observers.removeAll(where: { $0.identifier == observer.identifier }) } } private struct Observer: Equatable { let identifier: UUID let server: Server let handler: (NotificationManagerLocalPushStatus) -> Void static func == (lhs: Observer, rhs: Observer) -> Bool { lhs.identifier == rhs.identifier } } private var observers = [Observer]() private func pushManagerStateDidChange(server: Server) { for observer in observers where observer.server == server { observer.handler(status(for: server)) } } }