1//
2//  KBComponent.m
3//  Keybase
4//
5//  Created by Gabriel on 5/13/15.
6//  Copyright (c) 2015 Gabriel Handford. All rights reserved.
7//
8
9#import "KBComponentStatus.h"
10
11#import <ObjectiveSugar/ObjectiveSugar.h>
12
13
14@interface KBComponentStatus ()
15@property NSError *error;
16@property KBRInstallStatus installStatus;
17@property KBRInstallAction installAction;
18@property GHODictionary *info;
19@property NSString *label;
20@end
21
22@implementation KBComponentStatus
23
24+ (instancetype)componentStatusWithVersion:(KBSemVersion *)version bundleVersion:(KBSemVersion *)bundleVersion info:(GHODictionary *)info {
25  if (version && bundleVersion) {
26    if ([bundleVersion isGreaterThan:version]) {
27      return [KBComponentStatus componentStatusWithInstallStatus:KBRInstallStatusInstalled installAction:KBRInstallActionUpgrade info:info error:nil];
28    } else {
29      return [KBComponentStatus componentStatusWithInstallStatus:KBRInstallStatusInstalled installAction:KBRInstallActionNone info:info error:nil];
30    }
31  } else if (version && !bundleVersion) {
32    return [KBComponentStatus componentStatusWithInstallStatus:KBRInstallStatusInstalled installAction:KBRInstallActionNone info:info error:nil];
33  } else if (!version && bundleVersion) {
34    return [KBComponentStatus componentStatusWithInstallStatus:KBRInstallStatusNotInstalled installAction:KBRInstallActionInstall info:info error:nil];
35  }
36  return [KBComponentStatus componentStatusWithInstallStatus:KBRInstallStatusUnknown installAction:KBRInstallActionNone info:info error:nil];
37}
38
39+ (instancetype)componentStatusWithInstallStatus:(KBRInstallStatus)installStatus installAction:(KBRInstallAction)installAction info:(GHODictionary *)info error:(NSError *)error {
40  KBComponentStatus *componentStatus = [[KBComponentStatus alloc] init];
41  componentStatus.installStatus = installStatus;
42  componentStatus.installAction = installAction;
43  componentStatus.info = info;
44  componentStatus.error = error;
45  return componentStatus;
46}
47
48+ (instancetype)componentStatusWithError:(NSError *)error {
49  KBComponentStatus *componentStatus = [[KBComponentStatus alloc] init];
50  componentStatus.installStatus = KBRInstallStatusError;
51  componentStatus.installAction = KBRInstallActionNone;
52  componentStatus.error = error;
53  return componentStatus;
54}
55
56+ (instancetype)componentStatusWithServiceStatus:(KBRServiceStatus *)serviceStatus {
57  KBComponentStatus *componentStatus = [[KBComponentStatus alloc] init];
58  componentStatus.installStatus = serviceStatus.installStatus;
59  componentStatus.installAction = serviceStatus.installAction;
60  if (serviceStatus.status.code > 0) {
61    componentStatus.error = KBMakeError(serviceStatus.status.code, @"%@", serviceStatus.status.desc);
62  }
63  componentStatus.label = serviceStatus.label;
64
65  GHODictionary *info = [GHODictionary dictionary];
66  info[@"Version"] = KBIfBlank(serviceStatus.version, nil);
67
68  if (![serviceStatus.version isEqualToString:serviceStatus.bundleVersion]) {
69    info[@"Bundle Version"] = KBIfBlank(serviceStatus.bundleVersion, nil);
70  }
71
72  info[@"PID"] = KBIfBlank(serviceStatus.pid, nil);
73  info[@"Exit Status"] = KBIfBlank(serviceStatus.lastExitStatus, nil);
74
75  componentStatus.info = info;
76
77  return componentStatus;
78}
79
80- (BOOL)needsInstallOrUpgrade {
81  return _installAction == KBRInstallActionInstall
82    || _installAction == KBRInstallActionUpgrade
83    || _installAction == KBRInstallActionReinstall;
84}
85
86- (GHODictionary *)statusInfo {
87  GHODictionary *info = [GHODictionary dictionary];
88
89  if (self.error) {
90    info[@"Error"] = [self.error localizedDescription];
91  }
92
93  if (_info) [info addEntriesFromOrderedDictionary:_info];
94  info[@"Label"] = self.label;
95  info[@"Install Status"] = NSStringFromKBRInstallStatus(self.installStatus);
96  info[@"Install Action"] = NSStringFromKBRInstallAction(self.installAction);
97  return info;
98}
99
100- (NSString *)statusDescription:(NSString *)delimeter {
101  NSMutableArray *str = [NSMutableArray array];
102  [str addObject:NSStringFromKBRInstallStatus(_installStatus)];
103
104  NSMutableArray *infos = [NSMutableArray array];
105  for (id key in _info) {
106    [infos addObject:NSStringWithFormat(@"%@: %@", key, _info[key])];
107  }
108  if ([infos count] > 0) [str addObject:[infos join:delimeter]];
109
110  return [str join:@", "];
111}
112
113@end
114
115NSString *NSStringFromKBRInstallAction(KBRInstallAction action) {
116  switch (action) {
117    case KBRInstallActionNone: return nil;
118    case KBRInstallActionUnknown: return @"Unknown";
119    case KBRInstallActionInstall: return @"Install";
120    case KBRInstallActionUpgrade: return @"Upgrade";
121    case KBRInstallActionReinstall: return @"Re-Install";
122  }
123}
124
125NSString *NSStringFromKBRInstallStatus(KBRInstallStatus status) {
126  switch (status) {
127    case KBRInstallStatusError: return @"Error";
128    case KBRInstallStatusUnknown: return @"Unknown";
129    case KBRInstallStatusNotInstalled: return @"Not Installed";
130    case KBRInstallStatusInstalled: return @"Installed";
131  }
132}
133