// // AccountManager.swift // meterios // // (c) 2025 Martin "maride" Dessauer // import Foundation import SwiftUI /// **AccountManager** stores connection details and the corresponding client class AccountManager: ObservableObject { // default contains a ready-to-use instance of AccountManager, read from AppStorage static public var `default` = AccountManager() // accounts holds all saved accounts @Published private(set) var Accounts: Array = [] // init creates a new AccountManager, reading saved account data from AppStorage init() { self.Accounts = AccountManager.readFromRaw() } // readFromRaw reads the current accounts from the stored data and transforms it to a handy Account Array static private func readFromRaw() -> Array { @AppStorage("accounts") var rawAccs = Data() do { let simpleAccs = try JSONDecoder().decode([Account].self, from: rawAccs) let richAccs = simpleAccs.map({ AccountManagerEntry($0) }) return richAccs } catch { print("Error parsing stored accounts from JSON: \(error)") return [] } } // writeToRaw writes the current account data to the AppStorage private func writeToRaw() { @AppStorage("accounts") var rawAccs = Data() do { let simpleAccs = Accounts.map({ $0.GetAccount() }) rawAccs = try JSONEncoder().encode(simpleAccs) } catch { print("Error writing current accounts to JSON: \(error)") } } // CurrentAccount returns the currently selected account if there is one func CurrentAccount() -> AccountManagerEntry? { if self.Accounts.count > 0 { return self.Accounts.first } return nil } // AddAccount adds the given account if it doesn't exist yet func AddAccount(_ account: Account) { if IndexOfAccount(account) == nil { Accounts.append(AccountManagerEntry(account)) writeToRaw() } } // IndexOfAccount returns the index of the specified account identified by address and user ID func IndexOfAccount(_ account: Account) -> Int? { return Accounts.firstIndex(where: { $0.GetAccount().GetAddress() == account.GetAddress() && $0.GetAccount().GetUserID() == account.GetUserID() }) } // RemoveAccount removes the account specified by address and user ID of the given Account, if present func RemoveAccount(_ account: Account) { if IndexOfAccount(account) != nil { Accounts.remove(at: IndexOfAccount(account)!) writeToRaw() } } // RemoveAccount removes the account specified by address and user ID of the given AccountManagerEntry, if present func RemoveAccount(_ account: AccountManagerEntry) { RemoveAccount(account.GetAccount()) } }