/** * DailyNotificationStateActor.swift * * Actor for thread-safe state access * Serializes all access to shared state (database, storage, rolling window, TTL enforcer) * * @author Matthew Raymer * @version 1.0.0 */ import Foundation /** * Actor for thread-safe state access * * This actor serializes all access to: * - DailyNotificationDatabase * - DailyNotificationStorage * - DailyNotificationRollingWindow * - DailyNotificationTTLEnforcer * * All plugin methods and background tasks must access shared state through this actor. */ @available(iOS 13.0, *) actor DailyNotificationStateActor { // MARK: - Properties private let database: DailyNotificationDatabase private let storage: DailyNotificationStorage private let rollingWindow: DailyNotificationRollingWindow? private let ttlEnforcer: DailyNotificationTTLEnforcer? // MARK: - Initialization /** * Initialize state actor with components * * @param database Database instance * @param storage Storage instance * @param rollingWindow Rolling window instance (optional, Phase 2) * @param ttlEnforcer TTL enforcer instance (optional, Phase 2) */ init( database: DailyNotificationDatabase, storage: DailyNotificationStorage, rollingWindow: DailyNotificationRollingWindow? = nil, ttlEnforcer: DailyNotificationTTLEnforcer? = nil ) { self.database = database self.storage = storage self.rollingWindow = rollingWindow self.ttlEnforcer = ttlEnforcer } // MARK: - Storage Operations /** * Save notification content * * @param content Notification content to save */ func saveNotificationContent(_ content: NotificationContent) { storage.saveNotificationContent(content) } /** * Get notification content by ID * * @param id Notification ID * @return Notification content or nil */ func getNotificationContent(id: String) -> NotificationContent? { return storage.getNotificationContent(id: id) } /** * Get last notification * * @return Last notification or nil */ func getLastNotification() -> NotificationContent? { return storage.getLastNotification() } /** * Get all notifications * * @return Array of all notifications */ func getAllNotifications() -> [NotificationContent] { return storage.getAllNotifications() } /** * Get ready notifications * * @return Array of ready notifications */ func getReadyNotifications() -> [NotificationContent] { return storage.getReadyNotifications() } /** * Delete notification content * * @param id Notification ID */ func deleteNotificationContent(id: String) { storage.deleteNotificationContent(id: id) } /** * Clear all notifications */ func clearAllNotifications() { storage.clearAllNotifications() } // MARK: - Settings Operations /** * Save settings * * @param settings Settings dictionary */ func saveSettings(_ settings: [String: Any]) { storage.saveSettings(settings) } /** * Get settings * * @return Settings dictionary */ func getSettings() -> [String: Any] { return storage.getSettings() } // MARK: - Background Task Tracking /** * Save last successful run timestamp * * @param timestamp Timestamp in milliseconds */ func saveLastSuccessfulRun(timestamp: Int64) { storage.saveLastSuccessfulRun(timestamp: timestamp) } /** * Get last successful run timestamp * * @return Timestamp in milliseconds or nil */ func getLastSuccessfulRun() -> Int64? { return storage.getLastSuccessfulRun() } /** * Save BGTask earliest begin date * * @param timestamp Timestamp in milliseconds */ func saveBGTaskEarliestBegin(timestamp: Int64) { storage.saveBGTaskEarliestBegin(timestamp: timestamp) } /** * Get BGTask earliest begin date * * @return Timestamp in milliseconds or nil */ func getBGTaskEarliestBegin() -> Int64? { return storage.getBGTaskEarliestBegin() } // MARK: - Rolling Window Operations (Phase 2) /** * Maintain rolling window * * Phase 2: Rolling window maintenance */ func maintainRollingWindow() { // TODO: Phase 2 - Implement rolling window maintenance rollingWindow?.maintainRollingWindow() } // MARK: - TTL Enforcement Operations (Phase 2) /** * Validate content freshness before arming * * Phase 2: TTL validation * * @param content Notification content * @return true if content is fresh */ func validateContentFreshness(_ content: NotificationContent) -> Bool { // TODO: Phase 2 - Implement TTL validation guard let ttlEnforcer = ttlEnforcer else { return true // No TTL enforcement in Phase 1 } // TODO: Call ttlEnforcer.validateBeforeArming(content) return true } }