import Foundation import XXClient import XCTestDynamicOverlay public struct MessengerRestoreBackup { public struct Result: Equatable { public init( restoredParams: BackupParams, restoredContacts: [Data] ) { self.restoredParams = restoredParams self.restoredContacts = restoredContacts } public var restoredParams: BackupParams public var restoredContacts: [Data] } public var run: (Data, String) throws -> Result public func callAsFunction( backupData: Data, backupPassphrase: String ) throws -> Result { try run(backupData, backupPassphrase) } } extension MessengerRestoreBackup { public static func live(_ env: MessengerEnvironment) -> MessengerRestoreBackup { MessengerRestoreBackup { backupData, backupPassphrase in let storageDir = env.storageDir do { let ndfData = try env.downloadNDF(env.ndfEnvironment) let password = env.generateSecret() try env.passwordStorage.save(password) try env.fileManager.removeDirectory(storageDir) try env.fileManager.createDirectory(storageDir) let report = try env.newCMixFromBackup( ndfJSON: String(data: ndfData, encoding: .utf8)!, storageDir: storageDir, backupPassphrase: backupPassphrase, sessionPassword: password, backupFileContents: backupData ) let cMix = try env.loadCMix( storageDir: storageDir, password: password, cMixParamsJSON: env.getCMixParams() ) try cMix.startNetworkFollower(timeoutMS: 30_000) let e2e = try env.login( cMixId: cMix.getId(), authCallbacks: env.authCallbacks.registered(), identity: try cMix.makeReceptionIdentity(legacy: true), e2eParamsJSON: env.getE2EParams() ) let decoder = JSONDecoder() let paramsData = report.params.data(using: .utf8)! let params = try decoder.decode(BackupParams.self, from: paramsData) let ud = try env.newUdManagerFromBackup( params: NewUdManagerFromBackup.Params( e2eId: e2e.getId(), username: Fact(type: .username, value: params.username), email: params.email.map { Fact(type: .email, value: $0) }, phone: params.phone.map { Fact(type: .phone, value: $0) }, cert: env.udCert ?? e2e.getUdCertFromNdf(), contact: env.udContact ?? (try e2e.getUdContactFromNdf()), address: env.udAddress ?? e2e.getUdAddressFromNdf() ), follower: UdNetworkStatus { cMix.networkFollowerStatus() } ) env.cMix.set(cMix) env.e2e.set(e2e) env.ud.set(ud) env.isListeningForMessages.set(false) return Result( restoredParams: params, restoredContacts: report.restoredContacts ) } catch { try? env.fileManager.removeDirectory(storageDir) throw error } } } } extension MessengerRestoreBackup { public static let unimplemented = MessengerRestoreBackup( run: XCTUnimplemented("\(Self.self)") ) }