// // VehicleService.swift // AutoCatCore // // Created by Selim Mustafaev on 19.01.2025. // Copyright © 2025 Selim Mustafaev. All rights reserved. // public struct VehicleWithErrors: Sendable { public var vehicle: VehicleDto public var errors: [Error] } public final class VehicleService { let apiService: ApiServiceProtocol let storageService: StorageServiceProtocol let locationService: LocationServiceProtocol public init(apiService: ApiServiceProtocol, storageService: StorageServiceProtocol, locationService: LocationServiceProtocol) { self.apiService = apiService self.storageService = storageService self.locationService = locationService } } extension VehicleService: VehicleServiceProtocol { func check(number: String, forceUpdate: Bool, trackLocation: Bool, dbUpdatePolicy: DbUpdatePolicy) async throws -> VehicleWithErrors { var vehicle = (try? await storageService.loadVehicle(number: number)) ?? VehicleDto(number: number) var errors: [Error] = [] let events = vehicle.events let notes = vehicle.notes async let locationTask = trackLocation ? locationService.getRecentLocation() : nil async let vehicleTask = apiService.checkVehicle(by: number, notes: notes, events: events, force: forceUpdate) do { vehicle = try await vehicleTask } catch { errors.append(error) } if trackLocation { do { if let event = try await locationTask { vehicle.events.append(event) vehicle.synchronized = false if !vehicle.unrecognized { vehicle = try await apiService.add(event: event, to: number) } } } catch { errors.append(error) } } await locationService.resetLastEvent() try await storageService.updateVehicle(dto: vehicle, policy: dbUpdatePolicy) return VehicleWithErrors(vehicle: vehicle, errors: errors) } public func check(number: String) async throws -> VehicleWithErrors { try await check(number: number, forceUpdate: false, trackLocation: true, dbUpdatePolicy: .always) } public func updateHistory(number: String) async throws -> VehicleWithErrors { try await check(number: number, forceUpdate: true, trackLocation: false, dbUpdatePolicy: .always) } public func updateSearch(number: String) async throws -> VehicleWithErrors { try await check(number: number, forceUpdate: true, trackLocation: false, dbUpdatePolicy: .ifExists) } }