// // SampleRules.swift // Severed // import Foundation import SwiftData /// Builds deterministic rules for UI-test scenarios, positioned relative to /// "now" so an active window is genuinely active whenever the test runs. enum SampleRules { static func seed( _ scenario: LaunchConfiguration.SeedScenario, into context: ModelContext, now: Date = .now, calendar: Calendar = .current ) { switch scenario { case .standard: context.insert(activeRule(named: "Work Time", hardMode: false, now: now, calendar: calendar)) context.insert(upcomingRule(named: "Sleep", now: now, calendar: calendar)) case .hardModeActive: context.insert(activeRule(named: "Locked In", hardMode: true, now: now, calendar: calendar)) context.insert(upcomingRule(named: "Sleep", now: now, calendar: calendar)) } } /// A schedule rule whose window started up to an hour ago and runs for /// several hours, clamped so it never crosses midnight accidentally. static func activeRule( named name: String, hardMode: Bool, now: Date, calendar: Calendar = .current ) -> BlockingRule { let nowMinutes = minutesIntoDay(of: now, calendar: calendar) let start = max(0, nowMinutes - 60) let end = min(24 * 60 - 1, nowMinutes + 6 * 60) return BlockingRule( name: name, hardMode: hardMode, days: Weekday.everyDay, startMinutes: start, endMinutes: end ) } /// A schedule rule starting a couple of hours from now (possibly wrapping /// past midnight, which simply makes it start tomorrow). static func upcomingRule( named name: String, now: Date, calendar: Calendar = .current ) -> BlockingRule { let nowMinutes = minutesIntoDay(of: now, calendar: calendar) let start = (nowMinutes + 2 * 60) % (24 * 60) let end = (start + 8 * 60) % (24 * 60) return BlockingRule( name: name, days: Weekday.everyDay, startMinutes: start, endMinutes: end ) } private static func minutesIntoDay(of date: Date, calendar: Calendar) -> Int { let components = calendar.dateComponents([.hour, .minute], from: date) return (components.hour ?? 0) * 60 + (components.minute ?? 0) } }