1//
2//  PersistantState.m
3//  Security
4//
5//  Created by J Osborne on 7/11/13.
6//
7//
8
9#import "PersistantState.h"
10#import <Foundation/Foundation.h>
11
12@interface PersistantState()
13-(NSURL*)urlForStorage;
14@end
15
16@implementation PersistantState
17
18-(NSURL*)urlForStorage
19{
20    return [NSURL fileURLWithPath:@"/var/mobile/Library/Preferences/com.apple.security.CircleJoinRequested.plist" isDirectory:NO];
21}
22
23-(unsigned int)defaultPendingApplicationReminderAlertInterval
24{
25    return 60 * 60 * 24 * 2;
26}
27
28+(instancetype)loadFromStorage
29{
30    PersistantState *state = [[PersistantState alloc] init];
31    if (!state) {
32        return state;
33    }
34    
35    NSError *error = nil;
36    id plist = @{@"lastWritten": [NSDate distantPast]};
37    
38    NSData *stateData = [NSData dataWithContentsOfURL:[state urlForStorage] options:0 error:&error];
39    if (!stateData) {
40        NSLog(@"Can't read state data (p=%@, err=%@)", [state urlForStorage], error);
41    } else {
42        NSPropertyListFormat format;
43        id plistTmp = [NSPropertyListSerialization propertyListWithData:stateData options: NSPropertyListMutableContainersAndLeaves format:&format error:&error];
44        
45        if (plistTmp == nil) {
46            NSLog(@"Can't deserialize %@, e=%@", stateData, error);
47        } else {
48            plist = plistTmp;
49        }
50    }
51    
52    state.lastCircleStatus = plist[@"lastCircleStatus"] ? [plist[@"lastCircleStatus"] intValue] : kSOSCCCircleAbsent;
53    state.lastWritten = plist[@"lastWritten"];
54    state.pendingApplicationReminder = plist[@"pendingApplicationReminder"] ? plist[@"pendingApplicationReminder"] : [NSDate distantFuture];
55	state.applcationDate = plist[@"applcationDate"] ? plist[@"applcationDate"] : [NSDate distantPast];
56    state.debugShowLeftReason = plist[@"debugShowLeftReason"];
57    state.pendingApplicationReminderAlertInterval = plist[@"pendingApplicationReminderAlertInterval"] ? [plist[@"pendingApplicationReminderAlertInterval"] unsignedIntValue] : [state defaultPendingApplicationReminderAlertInterval];
58    state.absentCircleWithNoReason = plist[@"absentCircleWithNoReason"] ? [plist[@"absentCircleWithNoReason"] intValue] : NO;
59    
60    return state;
61}
62
63-(void)writeToStorage
64{
65    NSDictionary *plist = @{@"lastCircleStatus": [NSNumber numberWithInt:self.lastCircleStatus],
66                            @"lastWritten": [NSDate date],
67                            @"pendingApplicationReminder": self.pendingApplicationReminder ? self.pendingApplicationReminder : [NSDate distantFuture],
68							@"applcationDate": self.applcationDate ? self.applcationDate : [NSDate distantPast],
69                            @"pendingApplicationReminderAlertInterval": [NSNumber numberWithUnsignedInt:self.pendingApplicationReminderAlertInterval],
70                            @"absentCircleWithNoReason": [NSNumber numberWithBool:self.absentCircleWithNoReason]
71                            };
72    if (self.debugShowLeftReason) {
73        NSMutableDictionary *tmp = [plist mutableCopy];
74        tmp[@"debugShowLeftReason"] = self.debugShowLeftReason;
75        plist =[tmp copy];
76    }
77    NSLog(@"writeToStorage plist=%@", plist);
78    
79    NSError *error = nil;
80    NSData *stateData = [NSPropertyListSerialization dataWithPropertyList:plist format:NSPropertyListXMLFormat_v1_0 options:kCFPropertyListImmutable error:&error];
81    if (!stateData) {
82        NSLog(@"Can't serialize %@: %@", plist, error);
83        return;
84    }
85    if (![stateData writeToURL:[self urlForStorage] options:NSDataWritingAtomic error:&error]) {
86        NSLog(@"Can't write to %@, error=%@", [self urlForStorage], error);
87    }
88}
89
90@end
91