// // InheritanceServiceRecords.swift // Wallet // // Created by Igor on 11.03.2021. // Copyright © 2021 AM. All rights reserved. // import Foundation import WalletFoundation extension Inheritance.Service { final class Records: Common.Service.Provider { private var collection = [Model]() private var balances = [String: [Token]]() private(set) var waiting = [Model]() private(set) var ready = [Model]() var contract = Contract.cash } } extension Inheritance.Service.Records { func fetch(completion: @escaping Completion.Network) { waiting = [] ready = [] guard let username = Accounts().current?.name else { return } Network.Service.GraphQL.shared.fetchV2(query: InheritancesQuery(usernames: [username])) { result in switch result { case .success(let data): self.collection = data.reverseInheritance? .compactMap({ $0 }) .filter({ $0.smartContract == ApplicationEnvironment.shared().current.contract(self.contract) }) .map({ .init(data: $0) }) ?? [] self.fetchBalances { completion(nil) } case .failure(let error): completion(error as NSError?) } } } func execute(username: String, privateKey: String, _ completion: @escaping Completion.Network) { let inheritances = collection.filter({ $0.ownerUsername == username && $0.allowedToShare == true }) guard inheritances.count > 0, let balance = balances[username] else { completion(nil) return } var actions = [( contract: Network.Service.Blockchain.Contract, action: Network.Service.Blockchain.Action, data: Codable )]() for inheritance in inheritances { balance .filter { $0.contract == inheritance.smartContract } .forEach { token in ApplicationEnvironment.shared().current.contract(token.contract) >>- { contract in actions.append((contract, .dstrinh, [ "initiator": Accounts().current?.name ?? "", "inheritance_owner": inheritance.ownerUsername, "token": token.symbol ])) } } } Network.Service.Blockchain.execute(actions: actions, privateKeys: [privateKey]) { completion(.error($0)) } } } extension Inheritance.Service.Records { private func filter() { for user in collection { if user.allowedToShare == true, (balances[user.ownerUsername]?.filter({ $0.contract == user.smartContract && $0.amount > 0 }).count ?? 0) > 0, !ready.contains(where: { $0.ownerUsername == user.ownerUsername }) { ready.append(user) } else if !waiting.contains(where: { $0.ownerUsername == user.ownerUsername }) { waiting.append(user) } } } private func fetchBalances(_ completion: @escaping () -> Void) { fetchBalance(accounts: collection.filter({ $0.allowedToShare }).compactMap({ $0.ownerUsername })) { self.filter() completion() } } private func fetchBalance(accounts: [String], _ completion: @escaping () -> Void) { var accounts = accounts guard accounts.count > 0 else { completion() return } let account = accounts.first! // swiftlint:disable:this force_unwrapping accounts.removeFirst() Network.balance.fetch(account: account) { (collection, _) in self.balances[account] = collection.filter({ $0.amount > 0 }) self.fetchBalance(accounts: accounts, completion) } } } extension Inheritance.Service.Records { typealias Contract = EOSContract typealias Model = Inheritance.Model.Record typealias Token = Network.Model.Token }