+ (NSDictionary *)collectBatteryInfoIfNeeded {
    NSMutableDictionary *dictionary = [NSMutableDictionary new];
    UIDevice *device = [UIDevice currentDevice];
    BOOL originalBatteryMonitoringEnabled = device.isBatteryMonitoringEnabled;

    [device setBatteryMonitoringEnabled:YES];

    UIDeviceBatteryState batteryState = device.batteryState;
    NSNumber *batteryStateNumber = [NSNumber numberWithInteger:batteryState];
    [dictionary setObject:batteryStateNumber forKey:@"ict"];

    float batteryLevel = device.batteryLevel;
    int batteryPercentage = (int)(batteryLevel * 100);
    if (batteryPercentage > 0) {
        batteryPercentage = batteryPercentage ^ 0x10101010;
        NSNumber *batteryLevelNumber = @(batteryPercentage);
        [dictionary setObject:batteryLevelNumber forKey:@"icm"];
    }
    else {
        [dictionary setObject:@"-1" forKey:@"icm"];
    }

    [device setBatteryMonitoringEnabled:originalBatteryMonitoringEnabled];
    return dictionary;
}


+ (NSString *)collectModelRevision {
    struct utsname systemInfo;
    if (uname(&systemInfo) == 0) {
        NSString *modelString = [NSString stringWithUTF8String:systemInfo.machine];
        return modelString;
    }
    return nil;
}


+ (NSString *)collectSubplatform {
    if (@available(iOS 14.0, *)) {
        if ([[NSProcessInfo processInfo] isiOSAppOnMac]) {
            return @"ios_on_mac";
        }
    }

    if (@available(iOS 13.0, *)) {
        if ([[NSProcessInfo processInfo] isMacCatalystApp]) {
            return @"mac_catalyst";
        }
    }

    return @"ios"; 
}

+ (NSMutableDictionary *)collectScreenDimensions{
    NSMutableDictionary *dict = [NSMutableDictionary new];
    UIScreen *mainScreen = [UIScreen mainScreen];
    CGRect bounds = [mainScreen bounds];
    CGRect nativeBounds = [mainScreen nativeBounds];
    CGFloat scale = [mainScreen scale];

    [dict setObject:@(bounds.size.width) forKeyedSubscript:@"dx"];
    [dict setObject:@(bounds.size.height) forKeyedSubscript:@"dy"];
    [dict setObject:@(nativeBounds.size.width) forKeyedSubscript:@"ndx"];
    [dict setObject:@(nativeBounds.size.height) forKeyedSubscript:@"ndy"];
    [dict setObject:@(scale) forKeyedSubscript:@"scale"];

    return dict;
}


+ (NSDictionary *)collectBatteryInfoIfNeeded {
    NSMutableDictionary *dictionary = [NSMutableDictionary new];
    UIDevice *device = [UIDevice currentDevice];
    BOOL originalBatteryMonitoringEnabled = device.isBatteryMonitoringEnabled;

    [device setBatteryMonitoringEnabled:YES];

    UIDeviceBatteryState batteryState = device.batteryState;
    NSNumber *batteryStateNumber = [NSNumber numberWithInteger:batteryState];
    [dictionary setObject:batteryStateNumber forKey:@"ict"];

    float batteryLevel = device.batteryLevel;
    int batteryPercentage = (int)(batteryLevel * 100);
    if (batteryPercentage > 0) {
        batteryPercentage = batteryPercentage ^ 0x10101010;
        NSNumber *batteryLevelNumber = @(batteryPercentage);
        [dictionary setObject:batteryLevelNumber forKey:@"icm"];
    }
    else {
        [dictionary setObject:@"-1" forKey:@"icm"];
    }

    [device setBatteryMonitoringEnabled:originalBatteryMonitoringEnabled];
    return dictionary;
}

+ (id)collectTimeZoneOffset {
    NSTimeZone *tz = [NSTimeZone localTimeZone];
    NSInteger sec = [tz secondsFromGMT];
    double hoursFromGMT = (double)sec / 3600.0;
    return @(hoursFromGMT);
}

+ (void)userAgent {
    static WKWebView *webView = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        webView = [WKWebView new];
    });
    [webView evaluateJavaScript:@"function getAgent() {return navigator.userAgent;} getAgent(); " completionHandler:^(id _Nullable result, NSError * _Nullable error) {
        NSLog(@"zzh the useragent:%@ ",result);
    }];

}

+ (unsigned long long)collectAccessibilityFeatures {
    NSInteger features = 0;
    if (UIAccessibilityIsClosedCaptioningEnabled()) {
           features |= 0x2;
    }
    if (UIAccessibilityIsMonoAudioEnabled()) {
            features |= 0x4;
    }
    if (UIAccessibilityIsReduceMotionEnabled()) {
            features |= 0x8;
    }

    if (UIAccessibilityIsGuidedAccessEnabled()) {
        features |= 0x10;
    }

    if (UIAccessibilityIsInvertColorsEnabled()) {
        features |= 0x20;
    }

    if (UIAccessibilityIsVoiceOverRunning()) {
        features |= 0x40;
    }

    if (UIAccessibilityDarkerSystemColorsEnabled()) {
        features |= 0x80;
    }

    if (UIAccessibilityIsBoldTextEnabled()) {
        features |= 0x100;
    }

    if (UIAccessibilityIsGrayscaleEnabled()) {
        features |= 0x200;
    }

    if (UIAccessibilityIsReduceTransparencyEnabled()) {
        features |= 0x400;
    }

    if (UIAccessibilityIsSpeakScreenEnabled()) {
        features |= 0x800;
    }

    if (UIAccessibilityIsSpeakSelectionEnabled()) {
        features |= 0x1000;
    }

    if (UIAccessibilityIsSwitchControlRunning()) {
        features |= 0x2000;
    }

    if (UIAccessibilityIsShakeToUndoEnabled()) {
        features |= 0x4000;
    }

    if (UIAccessibilityIsAssistiveTouchRunning()) {
        features |= 0x8000;
    }

    if (UIAccessibilityHearingDevicePairedEar() != 0) {
        features |= 0x400000;
    }

    if (@available(iOS 13.0, *)) {
        if ([UITraitCollection currentTraitCollection].userInterfaceStyle == UIUserInterfaceStyleDark) {
            features |= 0x10000;
        }

        if (UIAccessibilityIsOnOffSwitchLabelsEnabled()) {
            features |= 0x20000;
        }

        if (UIAccessibilityIsVideoAutoplayEnabled()) {
            features |= 0x40000;
        }

        if (UIAccessibilityShouldDifferentiateWithoutColor()) {
            features |= 0x80000;
        }

        if (@available(iOS 14.0, *)) {
            if (UIAccessibilityPrefersCrossFadeTransitions()) {
                features |= 0x100000;
            }

            if (UIAccessibilityButtonShapesEnabled()) {
                features |= 0x200000;
            }

        }
    }
    NSLog(@"features:\n%ld",features);

    return features;
}

+ (long long)collectMonotonicRawClockTimeMillis {
    struct timespec tp;
    if(clock_gettime(CLOCK_MONOTONIC_RAW, &tp) != -1) {
        long  xx = tp.tv_sec*1000 + tp.tv_nsec/1000000;
        return xx;
    }
    return 0;
}

+ (NSString *)collectDeviceKeyboards{
    NSArray *lanagues = [NSLocale preferredLanguages];
    __block NSString *str = @"";
    [lanagues enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (idx < lanagues.count-1) {
            str = [str stringByAppendingFormat:@"%@,",obj];
        }
        else {
            str = [str stringByAppendingFormat:@"%@",obj];
        }


    }];
    return str;
}

+ (long long)collectKernelBootTimeMillis {
    struct timeval bootTime;
        int mib[2] = {CTL_KERN,KERN_BOOTTIME};
        size_t size = sizeof(bootTime);
        if (sysctl(mib, 2, &bootTime, &size, NULL, 0) != -1) {
            return bootTime.tv_sec * 1000;///秒
        };
        return 0;

}