summaryrefslogtreecommitdiff
path: root/LearnMapKit/DI/DependencyContainer.swift
blob: f0d1323cb6b95a65d90b210500fc6e125122ee3e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//
//  DependencyContainer.swift
//  LearnMapKit
//
//  Dependency injection container for the app
//

import Foundation

@MainActor
class DependencyContainer {

    // MARK: - Singletons
    lazy var configurationManager: ConfigurationManager = DefaultConfigurationManager()
    lazy var aircraftRepository: AircraftRepository = DefaultAircraftRepository(tracker: aircraftTracker)
    lazy var dataSourceFactory: DataSourceFactory = DefaultDataSourceFactory()
    lazy var aircraftTracker: AircraftTracker = DefaultAircraftTracker()

    // MARK: - ViewModels
    func makeAircraftTrackingViewModel() -> AircraftTrackingViewModel {
        AircraftTrackingViewModel(
            configurationManager: configurationManager,
            aircraftRepository: aircraftRepository,
            dataSourceFactory: dataSourceFactory
        )
    }

    func makeSettingsViewModel() -> SettingsViewModel {
        SettingsViewModel(configurationManager: configurationManager)
    }

    // MARK: - Data Sources (Factory Methods)
    func makeFileDataSource(configuration: FileDataSourceConfiguration) -> FileADSBDataSource {
        FileADSBDataSource(
            configuration: configuration,
            tracker: aircraftTracker
        )
    }

    func makeNetworkDataSource(configuration: NetworkDataSourceConfiguration) -> NetworkADSBDataSource {
        NetworkADSBDataSource(
            configuration: configuration,
            tracker: aircraftTracker
        )
    }
}

// MARK: - Settings ViewModel
@MainActor
class SettingsViewModel: ObservableObject {
    @Published var configuration: AppConfiguration
    @Published var hasUnsavedChanges: Bool = false
    @Published var validationErrors: [String] = []
    @Published var isValid: Bool = true

    private let configurationManager: ConfigurationManager
    private var cancellables = Set<AnyCancellable>()

    init(configurationManager: ConfigurationManager) {
        self.configurationManager = configurationManager
        self.configuration = configurationManager.getCurrentConfiguration()

        setupBindings()
    }

    func saveSettings() async {
        let validation = configurationManager.validateConfiguration(configuration)
        validationErrors = validation.errors
        isValid = validation.isValid

        if validation.isValid {
            do {
                await configurationManager.updateConfiguration(configuration)
                try await configurationManager.saveConfiguration()
            } catch {
                validationErrors = ["Failed to save: \(error.localizedDescription)"]
                isValid = false
            }
        }
    }

    func resetToDefaults() async {
        configuration = AppConfiguration.default
        await configurationManager.resetToDefaults()
    }

    func validateCurrentSettings() {
        let validation = configurationManager.validateConfiguration(configuration)
        validationErrors = validation.errors
        isValid = validation.isValid
    }

    private func setupBindings() {
        configurationManager.hasUnsavedChanges
            .receive(on: DispatchQueue.main)
            .assign(to: &$hasUnsavedChanges)

        $configuration
            .removeDuplicates()
            .sink { [weak self] _ in
                self?.validateCurrentSettings()
            }
            .store(in: &cancellables)
    }
}

// MARK: - Missing Protocol Implementations (Stubs)
protocol ADSBMessageDecoder {
    func decode(_ message: String) -> ADSBDataEvent?
}

class DefaultADSBMessageDecoder: ADSBMessageDecoder {
    func decode(_ message: String) -> ADSBDataEvent? {
        // This would contain the actual decoding logic
        // For now, return nil as a stub
        return nil
    }
}