 
 // MARK: Adding cards
 extension SecureChat {
-    private func generateRequest(forIdentityCard identityCard: VSSCard, keyPair: VSSKeyPair, isLtc: Bool) throws -> CreateEphemeralCardRequest {
+    private func generateRequest(forIdentityCard identityCard: VSSCard, keyPair: VSSKeyPair, isLtc: Bool) throws -> (CreateEphemeralCardRequest, String) {
         let identity = identityCard.identity
         let identityType = identityCard.identityType
         let device = self.preferences.deviceManager.getDeviceModel()

// MARK: Keys
extension SecureChat {
    static fileprivate let ServiceKeyName = "VIRGIL.SERVICE.INFO"
    static private let DateFormatRFC3339 = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
    static private let KeyNameFormat = "%@.%@.%@.%@"
    
    private func savePrivateKey(_ key: VSSPrivateKey, isLtc: Bool, dateStr: String) throws -> String {
        let privateKeyData = self.preferences.crypto.export(key, withPassword: nil)
        
        let keyName = String(format: SecureChat.KeyNameFormat, "VIRGIL", "OTKEY", dateStr, UUID().uuidString)
        let keyEntry = VSSKeyEntry(name: keyName, value: privateKeyData)
        
        try self.preferences.keyStorage.store(keyEntry)
        
        return keyName
    }
    
    private func savePrivateKeys(_ keys: [VSSPrivateKey], ltcKey: VSSPrivateKey?) throws -> ([String], String?) {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = SecureChat.DateFormatRFC3339
        let dateStr = dateFormatter.string(from: Date())
        
        var keyNames: [String] = []
        keyNames.reserveCapacity(keys.count)
        
        for privateKey in keys {
            keyNames.append(try self.savePrivateKey(privateKey, isLtc: false, dateStr: dateStr))
        }
        
        let ltcKeyName: String?
        if let ltcKey = ltcKey {
            ltcKeyName = try self.savePrivateKey(ltcKey, isLtc: true, dateStr: dateStr)
        }
        else {
            ltcKeyName = nil
        }
        
        return (keyNames, ltcKeyName)
    }
    
    fileprivate func generateAndSaveKeys(numberOfOtcKeys: Int, generateLtcKey: Bool) throws -> [VSSKeyPair] {
        let serviceInfo = try self.getServiceInfoEntry()
        
        var keyPairs: [VSSKeyPair] = []
        for _ in 0..<numberOfOtcKeys {
            keyPairs.append(self.preferences.crypto.generateKeyPair())
        }
        
        let ltcKeyPair = generateLtcKey ? self.preferences.crypto.generateKeyPair() : nil
        let (otcNames, ltcName) = try self.savePrivateKeys(keyPairs.map({ return $0.privateKey }), ltcKey: ltcKeyPair?.privateKey)
        
        let newServiceInfo = ServiceInfoEntry(ltcKeyName: generateLtcKey ? ltcName! : serviceInfo.ltcKeyName, otcKeysNames: serviceInfo.otcKeysNames + otcNames)
        
        try self.updateServiceInfoEntry(newEntry: newServiceInfo)
        
        return keyPairs
    }
    
    private func updateServiceInfoEntry(newEntry: ServiceInfoEntry) throws {

        self.virgilClient = VSSClient(serviceConfig: self.preferences.virgilServiceConfig)
    }

    public func initTalk(withRecipientWithIdentity identity: String, completion: @escaping (SecureTalk?, Error?)->()) {
        guard let identityCard = self.identityCard else {
            completion(nil, NSError(domain: SecureChat.ErrorDomain, code: -1, userInfo: [NSLocalizedDescriptionKey: "Identity card missing. Probably, SecureChat was not initialized."]))
            return
        }

        guard let publicKey = self.preferences.crypto.importPublicKey(from: identityCard.publicKeyData) else {
            completion(nil, NSError(domain: SecureChat.ErrorDomain, code: -1, userInfo: [NSLocalizedDescriptionKey: "Error importing public key from identity card."]))
            return
        }
        
        self.client.getRecipientCardsSet(forIdentities: [identity]) { cardsSets, error in
            guard error == nil else {
                completion(nil, NSError(domain: SecureChat.ErrorDomain, code: -1, userInfo: [NSLocalizedDescriptionKey: "Error obtaining recipient cards set."]))
                return
            }
            
            guard let cardsSets = cardsSets, cardsSets.count > 0 else {
                completion(nil, NSError(domain: SecureChat.ErrorDomain, code: -1, userInfo: [NSLocalizedDescriptionKey: "Error obtaining recipient cards set. Empty set."]))
                return
            }
            
            // FIXME: Multiple sessions?
            let cardsSet = cardsSets[0]
        
            
            let longTermPublicKeyData = cardsSet.longTermCard.publicKeyData
            let oneTimePublicKeyData = cardsSet.oneTimeCard.publicKeyData
            guard let oneTimePublicKey = self.preferences.crypto.importPublicKey(from: oneTimePublicKeyData),
                let longTermPublicKey = self.preferences.crypto.importPublicKey(from: longTermPublicKeyData) else {
                    completion(nil, NSError(domain: SecureChat.ErrorDomain, code: -1, userInfo: [NSLocalizedDescriptionKey: "Error importing eph public keys from cards."]))
                    return
            }

            let secureTalk = SecureTalk(crypto: self.preferences.crypto, myPrivateKey: self.preferences.myPrivateKey, ephPrivateKey: self.preferences.crypto.generateKeyPair().privateKey, recipientPublicKey: publicKey, recipientLongTermKey: longTermPublicKey, recipientOneTimeKey: oneTimePublicKey)
            
            completion(secureTalk, nil)
        }
    }
}

