<commit_before>//
//  AccountStore.swift
//  VimeoNetworkingExample-iOS
//
//  Created by <NAME> on 3/24/16.
//  Copyright © 2016 Vimeo. All rights reserved.
//

import Foundation

final internal class AccountStore
{
    enum AccountType: String
    {
        case ClientCredentials
        case User
    }
    
    // MARK: - 
    
    private let dataStore: SecureDataStore
    
    // MARK: -
    
    init(configuration: AppConfiguration)
    {
        self.dataStore = KeychainStore(service: configuration.keychainService, accessGroup: configuration.keychainAccessGroup)
    }
    
    // MARK: -
    
    func saveAccount(account: VIMAccount, type: AccountType) throws
    {
        let data = NSMutableData()
        let archiver = NSKeyedArchiver(forWritingWithMutableData: data)
        archiver.encodeObject(account)
        archiver.finishEncoding()
        
        try self.dataStore.setData(data, forKey: type.rawValue)
    }
    
    func loadAccount(type: AccountType) throws -> VIMAccount?
    {
        guard let data = try self.dataStore.dataForKey(type.rawValue)
        else
        {
            return nil
        }
        
        let unarchiver = NSKeyedUnarchiver(forReadingWithData: data)
        
        var account: VIMAccount? = nil
        
        try ExceptionCatcher.doUnsafe
        {
            account = unarchiver.decodeObject() as? VIMAccount
        }
        
        if let account = account,
            let userJSON = account.userJSON as? VimeoClient.ResponseDictionary
        {
            try account.user = VIMObjectMapper.mapObject(userJSON) as VIMUser
        }
        
        return account
    }
    
    func removeAccount(type: AccountType) throws
    {
        try self.dataStore.deleteDataForKey(type.rawValue)
    }
}<commit_msg>Delete corrupted account store data on a failed load<commit_after>//
//  AccountStore.swift
//  VimeoNetworkingExample-iOS
//
//  Created by <NAME> on 3/24/16.
//  Copyright © 2016 Vimeo. All rights reserved.
//

import Foundation

final internal class AccountStore
{
    enum AccountType: String
    {
        case ClientCredentials
        case User
    }
    
    // MARK: - 
    
    private static let ErrorDomain = "AccountStoreErrorDomain"
    
    // MARK: - 
    
    private let dataStore: SecureDataStore
    
    // MARK: -
    
    init(configuration: AppConfiguration)
    {
        self.dataStore = KeychainStore(service: configuration.keychainService, accessGroup: configuration.keychainAccessGroup)
    }
    
    // MARK: -
    
    func saveAccount(account: VIMAccount, type: AccountType) throws
    {
        let data = NSMutableData()
        let archiver = NSKeyedArchiver(forWritingWithMutableData: data)
        archiver.encodeObject(account)
        archiver.finishEncoding()
        
        try self.dataStore.setData(data, forKey: type.rawValue)
    }
    
    func loadAccount(type: AccountType) throws -> VIMAccount?
    {
        do
        {
            guard let data = try self.dataStore.dataForKey(type.rawValue)
            else
            {
                return nil
            }
            
            let unarchiver = NSKeyedUnarchiver(forReadingWithData: data)
            var decodedAccount: VIMAccount? = nil
            try ExceptionCatcher.doUnsafe
            {
                decodedAccount = unarchiver.decodeObject() as? VIMAccount
            }
            
            guard let account = decodedAccount
            else
            {
                let description = "Received corrupted VIMAccount data from keychain"
                let error = NSError(domain: self.dynamicType.ErrorDomain, code: LocalErrorCode.AccountCorrupted.rawValue, userInfo: [NSLocalizedDescriptionKey: description])
                
                throw error
            }
            
            if let userJSON = account.userJSON as? VimeoClient.ResponseDictionary
            {
                try account.user = VIMObjectMapper.mapObject(userJSON) as VIMUser
            }
            
            return account
        }
        catch let error
        {
            _ = try? self.removeAccount(type)
            
            throw error
        }
    }
    
    func removeAccount(type: AccountType) throws
    {
        try self.dataStore.deleteDataForKey(type.rawValue)
    }
}
{'fraction_non_alphanumeric': 0.07301808066759388, 'fraction_numerical': 0.004172461752433936, 'mean_word_length': 1.7928802588996764, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5038343', 'n_tokens_mistral': 1220, 'n_tokens_neox': 1160, 'n_words': 263}