// // CloudKitDataProvider.swift // SportsTime // // Wraps CloudKitService to conform to DataProvider protocol // import Foundation actor CloudKitDataProvider: DataProvider { private let cloudKit = CloudKitService.shared // MARK: - Availability func checkAvailability() async throws { try await cloudKit.checkAvailabilityWithError() } // MARK: - DataProvider Protocol func fetchTeams(for sport: Sport) async throws -> [Team] { do { try await checkAvailability() return try await cloudKit.fetchTeams(for: sport) } catch { throw CloudKitError.from(error) } } func fetchAllTeams() async throws -> [Team] { do { try await checkAvailability() var allTeams: [Team] = [] for sport in Sport.supported { let teams = try await cloudKit.fetchTeams(for: sport) allTeams.append(contentsOf: teams) } return allTeams } catch { throw CloudKitError.from(error) } } func fetchStadiums() async throws -> [Stadium] { do { try await checkAvailability() return try await cloudKit.fetchStadiums() } catch { throw CloudKitError.from(error) } } func fetchGames(sports: Set, startDate: Date, endDate: Date) async throws -> [Game] { do { try await checkAvailability() return try await cloudKit.fetchGames(sports: sports, startDate: startDate, endDate: endDate) } catch { throw CloudKitError.from(error) } } func fetchGame(by id: UUID) async throws -> Game? { do { try await checkAvailability() return try await cloudKit.fetchGame(by: id) } catch { throw CloudKitError.from(error) } } func fetchRichGames(sports: Set, startDate: Date, endDate: Date) async throws -> [RichGame] { do { try await checkAvailability() // Fetch all required data async let gamesTask = cloudKit.fetchGames(sports: sports, startDate: startDate, endDate: endDate) async let teamsTask = fetchAllTeamsInternal() async let stadiumsTask = cloudKit.fetchStadiums() let (games, teams, stadiums) = try await (gamesTask, teamsTask, stadiumsTask) let teamsById = Dictionary(uniqueKeysWithValues: teams.map { ($0.id, $0) }) let stadiumsById = Dictionary(uniqueKeysWithValues: stadiums.map { ($0.id, $0) }) return games.compactMap { game in guard let homeTeam = teamsById[game.homeTeamId], let awayTeam = teamsById[game.awayTeamId], let stadium = stadiumsById[game.stadiumId] else { return nil } return RichGame(game: game, homeTeam: homeTeam, awayTeam: awayTeam, stadium: stadium) } } catch { throw CloudKitError.from(error) } } // Internal helper to avoid duplicate availability checks private func fetchAllTeamsInternal() async throws -> [Team] { var allTeams: [Team] = [] for sport in Sport.supported { let teams = try await cloudKit.fetchTeams(for: sport) allTeams.append(contentsOf: teams) } return allTeams } }