1//
2//  RNBranchConfig.m
3//  Pods
4//
5//  Created by Jimmy Dee on 6/7/17.
6//
7//
8
9#import <React/RCTLog.h>
10
11#import "RNBranchConfig.h"
12
13NSString * _Nonnull const RNBranchConfigDebugModeOption = @"debugMode";
14NSString * _Nonnull const RNBranchConfigBranchKeyOption = @"branchKey";
15NSString * _Nonnull const RNBranchConfigLiveKeyOption = @"liveKey";
16NSString * _Nonnull const RNBranchConfigTestKeyOption = @"testKey";
17NSString * _Nonnull const RNBranchConfigUseTestInstanceOption = @"useTestInstance";
18NSString * _Nonnull const RNBranchConfigDelayInitToCheckForSearchAdsOption = @"delayInitToCheckForSearchAds";
19NSString * _Nonnull const RNBranchConfigAppleSearchAdsDebugModeOption = @"appleSearchAdsDebugMode";
20NSString * _Nonnull const RNBranchConfigDeferInitializationForJSLoadOption = @"deferInitializationForJSLoad";
21NSString * _Nonnull const RNBranchConfigEnableFacebookLinkCheck = @"enableFacebookLinkCheck";
22
23NSString * const RNBNC_PLUGIN_VERSION = RNBRANCH_VERSION;
24
25@interface RNBranchConfig()
26@property (nonatomic) NSDictionary *configuration;
27@property (nonatomic, readonly) NSData *configFileContents;
28@property (nonatomic) NSURL *configFileURL;
29@end
30
31@implementation RNBranchConfig
32
33+ (RNBranchConfig * _Nonnull)instance
34{
35    @synchronized(self) {
36        static RNBranchConfig *_instance;
37        static dispatch_once_t once = 0;
38        dispatch_once(&once, ^{
39            _instance = [[RNBranchConfig alloc] init];
40        });
41        return _instance;
42    }
43}
44
45- (instancetype)init
46{
47    self = [super init];
48    if (self) {
49        [self findConfigFile];
50        [self loadConfigFile];
51    }
52    return self;
53}
54
55- (void)loadConfigFile
56{
57    NSData *data = self.configFileContents;
58    if (!data) return;
59
60    NSError *error;
61    id object = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
62    if (!object || error) {
63        RCTLogError(@"Failed to parse branch.json. Error: %@", error.localizedDescription);
64        return;
65    }
66
67    if (![object isKindOfClass:NSDictionary.class]) {
68        RCTLogError(@"Contents of branch.json should be a JSON object.");
69        return;
70    }
71
72    self.configuration = object;
73}
74
75- (NSData *)configFileContents
76{
77    if (!self.configFileURL) return nil;
78    RCTLogInfo(@"Loading %@", self.configFileURL.pathComponents.lastObject);
79
80    NSError *error;
81    NSData *data = [NSData dataWithContentsOfURL:self.configFileURL options:0 error:&error];
82    if (!data || error) {
83        RCTLogError(@"Failed to load %@. Error: %@", self.configFileURL, error.localizedDescription);
84        return nil;
85    }
86    return data;
87}
88
89- (void)findConfigFile
90{
91    if (self.configFileURL) return;
92
93    __block NSURL *configFileURL;
94    NSBundle *mainBundle = NSBundle.mainBundle;
95    NSArray *filesToCheck =
96    @[
97#ifdef DEBUG
98      @"branch.ios.debug",
99      @"branch.debug",
100#endif // DEBUG
101      @"branch.ios",
102      @"branch"
103      ];
104
105    [filesToCheck enumerateObjectsUsingBlock:^(NSString *  _Nonnull file, NSUInteger idx, BOOL * _Nonnull stop) {
106        configFileURL = [mainBundle URLForResource:file withExtension:@"json"];
107        *stop = (configFileURL != nil);
108    }];
109
110    if (!configFileURL) {
111        RCTLogInfo(@"Could not find branch.json in app bundle.");
112        return;
113    }
114
115    self.configFileURL = configFileURL;
116}
117
118- (BOOL)debugMode
119{
120    NSNumber *number = self[RNBranchConfigDebugModeOption];
121    return number.boolValue;
122}
123
124- (BOOL)useTestInstance
125{
126    NSNumber *number = self[RNBranchConfigUseTestInstanceOption];
127    return number.boolValue;
128}
129
130- (BOOL)delayInitToCheckForSearchAds
131{
132    NSNumber *number = self[RNBranchConfigDelayInitToCheckForSearchAdsOption];
133    return number.boolValue;
134}
135
136- (BOOL)appleSearchAdsDebugMode
137{
138    NSNumber *number = self[RNBranchConfigAppleSearchAdsDebugModeOption];
139    return number.boolValue;
140}
141
142- (BOOL)deferInitializationForJSLoad
143{
144    NSNumber *number = self[RNBranchConfigDeferInitializationForJSLoadOption];
145    return number.boolValue;
146}
147
148- (BOOL)enableFacebookLinkCheck
149{
150    NSNumber *number = self[RNBranchConfigEnableFacebookLinkCheck];
151    return number.boolValue;
152}
153
154- (NSString *)branchKey
155{
156    return self[RNBranchConfigBranchKeyOption];
157}
158
159- (NSString *)liveKey
160{
161    return self[RNBranchConfigLiveKeyOption];
162}
163
164- (NSString *)testKey
165{
166    return self[RNBranchConfigTestKeyOption];
167}
168
169- (id)objectForKey:(NSString *)key
170{
171    return self.configuration[key];
172}
173
174- (id)objectForKeyedSubscript:(NSString *)key
175{
176    return self.configuration[key];
177}
178
179@end
180