#import "TDKeychainItemWrapper.h"
#import "TDLogging.h"

static NSString * const TDKeychainService = @"com.thinkingddata.analytics.service";
static NSString * const TDInstallTimes = @"com.thinkingddata.analytics.installtimes";
static NSString * const TDDeviceID = @"com.thinkingddata.analytics.deviceid";

@interface TDKeychainItemWrapper ()

@property (atomic, strong) NSDictionary *oldKeychain;

@end

@implementation TDKeychainItemWrapper

- (void)saveItem:(NSString *)string forKey:(NSString *)key {
    NSData *encodeData = [string dataUsingEncoding:NSUTF8StringEncoding];
    NSString *originPassword = [self dataForKey:key];
    if (originPassword.length > 0) {
        NSMutableDictionary *updateAttributes = [NSMutableDictionary dictionary];
        updateAttributes[(__bridge id)kSecValueData] = encodeData;
        NSMutableDictionary *query = [self keychainQueryWithAccount:key];
        OSStatus statusCode = SecItemUpdate((__bridge CFDictionaryRef)query,(__bridge CFDictionaryRef)updateAttributes);
        if (statusCode != noErr) {
            TDLogError(@"Couldn't update the Keychain Item." );
        }
    } else {
        NSMutableDictionary *attributes = [self keychainQueryWithAccount:key];
        attributes[(__bridge id)kSecValueData] = encodeData;
        OSStatus statusCode = SecItemAdd((__bridge CFDictionaryRef)attributes, nil);
        if (statusCode != noErr) {
            TDLogError(@"Couldn't add the Keychain Item.");
        }
    }
}

- (void)saveInstallTimes:(NSString *)string {
    [self saveItem:string forKey:TDInstallTimes];
}

- (void)saveDeviceId:(NSString *)string {
    [self saveItem:string forKey:TDDeviceID];
}

- (NSString *)dataForKey:(NSString *)key {
    NSMutableDictionary *attributes = [self keychainQueryWithAccount:key];
    attributes[(__bridge id)kSecMatchLimit] = (__bridge id)(kSecMatchLimitOne);
    attributes[(__bridge id)kSecReturnData] = (__bridge id)(kCFBooleanTrue);
    CFTypeRef data = nil;
    OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)attributes,(CFTypeRef *)&data);
    if (status != errSecSuccess) {
        return nil;
    }
    NSData *encodeData = [NSData dataWithData:(__bridge NSData *)data];
    if (data) {
        CFRelease(data);
    }
    if (encodeData) {
        return [[NSString alloc] initWithData:encodeData encoding:NSUTF8StringEncoding];
    }
    
    return nil;
}

- (void)readOldKeychain {
    NSMutableDictionary *genericPasswordQuery = [[NSMutableDictionary alloc] init];
    [genericPasswordQuery setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
    [genericPasswordQuery setObject:@"ThinkingdataService" forKey:(__bridge id)kSecAttrGeneric];
    [genericPasswordQuery setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
    [genericPasswordQuery setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnAttributes];
    NSDictionary *tempQuery = [NSDictionary dictionaryWithDictionary:genericPasswordQuery];
    CFTypeRef cfDictionary = NULL;
    if (SecItemCopyMatching((__bridge CFDictionaryRef)tempQuery, &cfDictionary) == noErr) {
        NSMutableDictionary *returnDict = [NSMutableDictionary dictionaryWithDictionary:(__bridge_transfer NSDictionary *)cfDictionary];
        [returnDict setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
        [returnDict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
        
        OSStatus keychainErr = noErr;
        CFTypeRef cfXmlData = NULL;
        keychainErr = SecItemCopyMatching((__bridge CFDictionaryRef)returnDict, &cfXmlData);
        
        if (keychainErr == noErr) {
            NSData *xmlData = (__bridge_transfer NSData *)cfXmlData;
            NSPropertyListFormat fmt;
            NSDictionary *resultsInfo = [NSPropertyListSerialization propertyListWithData:xmlData options:NSPropertyListMutableContainersAndLeaves format:&fmt error:nil];
            self.oldKeychain = resultsInfo;
        }
    }
}

- (NSString *)getInstallTimesOld {
    if (self.oldKeychain)
        return [NSString stringWithFormat:@"%@",[self.oldKeychain objectForKey:@"thinking_setup_index"]];
    return nil;
}

- (NSString *)getDeviceIdOld {
    if (self.oldKeychain)
        return [self.oldKeychain objectForKey:@"thinking_device_id"];
    return nil;
}

- (NSString *)readDeviceId {
    NSString *data = [self dataForKey:TDDeviceID];
    return data;
}

- (NSString *)readInstallTimes {
    NSString *data = [self dataForKey:TDInstallTimes];
    return data;
}

- (NSMutableDictionary *)keychainQueryWithAccount:(NSString *)account {
    NSMutableDictionary *query = [NSMutableDictionary dictionary];
    query[(__bridge id)kSecClass] = (__bridge id)kSecClassGenericPassword;
    query[(__bridge id)kSecAttrService] = TDKeychainService;
    query[(__bridge id)kSecAttrAccount] = account;
    return query;
}

@end
