//
//  DeviceInformation.m
//  MobilePortal
//
//  Created by xiejiangbo on 2019/9/4.
//  Copyright © 2019 yin chen. All rights reserved.
//

#import "DeviceInformation.h"
#import "DeviceInfoManager.h"
#import "NetWorkInfoManager.h"
#import "BatteryInfoManager.h"
#include <sys/param.h>
#include <sys/mount.h>
#import "ModelJudgeFunc.h"
#import "sys/utsname.h"

// 下面是获取mac地址需要导入的头文件
#include <sys/socket.h> // Per msqr
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>


#import <sys/sockio.h>
#import <sys/ioctl.h>
#import <arpa/inet.h>

// 下面是获取ip需要的头文件
#include <ifaddrs.h>


#include <mach/mach.h> // 获取CPU信息所需要引入的头文件
//#include <arpa/inet.h>
//#include <ifaddrs.h>

#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>


extern NSString * CTSettingCopyMyPhoneNumber(void);
extern NSString * CTSIMSupportCopyMobileSubscriberIdentity(void);

@implementation DeviceInformation

+ (DeviceInformation *)ShareDeviceInformation{
    static DeviceInformation *baseTabBarView = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        baseTabBarView = [[DeviceInformation alloc]init];
    });
    return baseTabBarView;
}
-(NSMutableDictionary *)getDeviceInformation:(NSMutableDictionary *)dic{
    NSMutableDictionary *attrDic = [NSMutableDictionary dictionary];
    BatteryInfoManager *batteryManager = [BatteryInfoManager sharedManager];
    [batteryManager startBatteryMonitoring];
    //可用容量
    attrDic[kHttpDeviceInformationHttpCmd_available_capacity] = [self getDivceSize];
    //电池电量
    attrDic[kHttpDeviceInformationHttpCmd_battery_level] = [NSString stringWithFormat:@"%d %%",[self getCurrentBatteryLevel]];
    //蓝牙地址MAC地址
    attrDic[kHttpDeviceInformationHttpCmd_bluetooth_address] = [[DeviceInfoManager sharedManager] getMacAddress];
    //编译版本 系统版本
    attrDic[kHttpDeviceInformationHttpCmd_compile_version] = [UIDevice currentDevice].systemVersion;
    
    //设备ChangeID
    attrDic[kHttpDeviceInformationHttpCmd_device_changeid] = [AccountInfo sharedInstance].appUUID;
    attrDic[kHttpDeviceInformationHttpCmd_device_channelid] = @"";
    //设备型号 iphone67
    attrDic[kHttpDeviceInformationHttpCmd_device_model] = [ModelJudgeFunc deviceModelName];
    //设备名称某某的苹果
    attrDic[kHttpDeviceInformationHttpCmd_device_name] = [UIDevice currentDevice].name;
    //设备序列号 空
    attrDic[kHttpDeviceInformationHttpCmd_device_sid] = [AccountInfo sharedInstance].appUUID;
    //设备类型iPhone
    attrDic[kHttpDeviceInformationHttpCmd_device_type] = [UIDevice currentDevice].localizedModel;
    //设备UserID手机用户的id？？？？？
    attrDic[kHttpDeviceInformationHttpCmd_device_userid] = [AccountInfo sharedInstance].appUUID;
    //设备唯一编号imei
    attrDic[kHttpDeviceInformationHttpCmd_id] = [AccountInfo sharedInstance].appUUID;
    //IMEI 设备序列号imei
    attrDic[kHttpDeviceInformationHttpCmd_imei] = CTSIMSupportCopyMobileSubscriberIdentity();
    //最新位置
    attrDic[kHttpDeviceInformationHttpCmd_latest_position] = [AccountInfo sharedInstance].address;
    //登录时间
    attrDic[kHttpDeviceInformationHttpCmd_login_date] = [self currentTimeStr];
    //调制解调器固件
    attrDic[kHttpDeviceInformationHttpCmd_modem_firmware] = @"";
    //运营商
    attrDic[kHttpDeviceInformationHttpCmd_operators] = [self getcarrierName];
    
    attrDic[kHttpDeviceInformationHttpCmd_optno] = @"";
    // 网络类型
    attrDic[kHttpDeviceInformationHttpCmd_netstat] = [SNHttpBaseCmd getNetconnType];
    //手机号码 不能上线
    //    CTTelephonyNetworkInfo *info = [[CTTelephonyNetworkInfo alloc] init];
    //    CTCarrier *carrier = info.subscriberCellularProvider;
    
    
    //NSLog(@"%@",[[NSUserDefaults standardUserDefaults] stringForKey:@"SBFormattedPhoneNumber"]);
    attrDic[kHttpDeviceInformationHttpCmd_phone_number] = CTSettingCopyMyPhoneNumber();
    attrDic[kHttpDeviceInformationHttpCmd_phone_number] = @"";
    //平台类型iphone
    attrDic[kHttpDeviceInformationHttpCmd_platform] = [UIDevice currentDevice].systemName;
    //最后推送时间
    attrDic[kHttpDeviceInformationHttpCmd_push_date] = @"";
    //备注
    attrDic[kHttpDeviceInformationHttpCmd_remark] = @"";
    //是否有效(Y-有效 ; N-无效)
    attrDic[kHttpDeviceInformationHttpCmd_status] = @"Y";
    //存储容量
    attrDic[kHttpDeviceInformationHttpCmd_storage_capacity] = [self getDivceSizetoTalCapacity];
    //系统版本8.0
    attrDic[kHttpDeviceInformationHttpCmd_sys_version] = [UIDevice currentDevice].systemVersion;
    
    attrDic[kHttpDeviceInformationHttpCmd_user_id] = [AccountInfo sharedInstance].UserId;
    //无线局域网地址无线MAC地址
    attrDic[kHttpDeviceInformationHttpCmd_wlan_address] = [[NetWorkInfoManager sharedManager] getDeviceIPAddresses];
    attrDic[kHttpDeviceInformationHttpCmd_equipmentversion] = @"N";
    /// App 版本号
    NSString*systemversion=[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
    attrDic[kHttpDeviceInformationHttpCmd_app_version] = systemversion;
    dic[kHttpDeviceInformationHttpCmd_attr] = attrDic;
    
    return attrDic;
}
//获取可用
- (NSString *)getDivceSize{
    struct statfs buf;
    unsigned long long freeSpace = -1;
    if(statfs("/var", &buf) >=0){
        freeSpace = (unsigned long long)(buf.f_bsize * buf.f_bavail);
        
    }
//    NSLog(@"%@",[self fileSizeToString:freeSpace]);
    return [self fileSizeToString:freeSpace];
    //可用大小
//    struct statfs buf;
//    long long freespace = -1;
//    if(statfs("/var", &buf) >= 0){
//        freespace = (long long)(buf.f_bsize * buf.f_bfree);
//    }
//    NSString * sizeStr = [NSString stringWithFormat:@"%0.2fG",(double)freespace/1024/1024/1024];
//    return  sizeStr;
}
//获取总容量
- (NSString *)getDivceSizetoTalCapacity{
    struct statfs buf;
    unsigned long long freeSpace = -1;
    if(statfs("/var", &buf) >=0)
    {
        freeSpace = (unsigned long long)(buf.f_bsize * buf.f_blocks);
        
    }
//    NSLog(@"%@",[self fileSizeToString:freeSpace]);
    return [self fileSizeToString:freeSpace];
    //总大小
//    struct statfs buf1;
//    long long maxspace = 0;
//    if (statfs("/", &buf1) >= 0) {
//        maxspace = (long long)buf1.f_bsize * buf1.f_blocks;
//    }
//    if (statfs("/private/var", &buf1) >= 0) {
//        maxspace += (long long)buf1.f_bsize * buf1.f_blocks;
//    }
//    NSString * sizeStr = [NSString stringWithFormat:@"%0.2fG",(double)maxspace/1024/1024/1024];
//    return  sizeStr;
}
-(NSString*)fileSizeToString:(unsigned long long)fileSize{
    NSInteger KB =1024;
    NSInteger MB = KB*KB;
    NSInteger GB = MB*KB;
    if(fileSize <10){
        return@"0 B";
    }else if(fileSize < KB){
        return@"< 1 KB";
    }else if(fileSize < MB){
        return [NSString stringWithFormat:@"%.1f KB",((CGFloat)fileSize)/KB];
        
    }else if(fileSize < GB){
        return [NSString stringWithFormat:@"%.1f MB",((CGFloat)fileSize)/MB];
        
    }else{
        return [NSString stringWithFormat:@"%.1f GB",((CGFloat)fileSize)/GB];
    }
    
}
//电池电量
-(NSString *)getBatteryQuantity
{
    
    return [NSString stringWithFormat:@"%f",[[UIDevice currentDevice] batteryLevel]];;
}
//mac 地址
- (NSString *)getMacAddress {
    int mib[6];
    size_t len;
    char *buf;
    unsigned char *ptr;
    struct if_msghdr *ifm;
    struct sockaddr_dl *sdl;
    
    mib[0] = CTL_NET;
    mib[1] = AF_ROUTE;
    mib[2] = 0;
    mib[3] = AF_LINK;
    mib[4] = NET_RT_IFLIST;
    
    if ((mib[5] = if_nametoindex("en0")) == 0) {
        printf("Error: if_nametoindex error/n");
        return NULL;
    }
    
    if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
        printf("Error: sysctl, take 1/n");
        return NULL;
    }
    
    if ((buf = malloc(len)) == NULL) {
        printf("Could not allocate memory. error!/n");
        return NULL;
    }
    
    if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
        printf("Error: sysctl, take 2");
        return NULL;
    }
    
    ifm = (struct if_msghdr *)buf;
    sdl = (struct sockaddr_dl *)(ifm + 1);
    ptr = (unsigned char *)LLADDR(sdl);
    
    NSString *outstring = [NSString stringWithFormat:@"%02x:%02x:%02x:%02x:%02x:%02x", *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];
    free(buf);
    
    return [outstring uppercaseString];
}
//获取运营商
-(NSString *)getcarrierName{
    CTTelephonyNetworkInfo *telephonyInfo = [[CTTelephonyNetworkInfo alloc] init];
    CTCarrier *carrier = [telephonyInfo subscriberCellularProvider];
    //NSString *currentCountry=[carrier carrierName];
    return [carrier carrierName];
}
//获取当前时间戳
- (NSString *)currentTimeStr{
    NSDate* date = [NSDate dateWithTimeIntervalSinceNow:0];//获取当前时间0秒后的时间
    NSTimeInterval time=[date timeIntervalSince1970]*1000;// *1000 是精确到毫秒，不乘就是精确到秒
    NSString *timeString = [NSString stringWithFormat:@"%.0f", time];
    return timeString;
}

- (int)getCurrentBatteryLevel

{
    
    UIApplication *app = [UIApplication sharedApplication];
    
    if (app.applicationState == UIApplicationStateActive||app.applicationState==UIApplicationStateInactive) {
        
        Ivar ivar=  class_getInstanceVariable([app class],"_statusBar");
        
        id status  = object_getIvar(app, ivar);
        
        for (id aview in [status subviews]) {
            
            int batteryLevel = 0;
            
            for (id bview in [aview subviews]) {
                
                if ([NSStringFromClass([bview class]) caseInsensitiveCompare:@"UIStatusBarBatteryItemView"] == NSOrderedSame&&[[[UIDevice currentDevice] systemVersion] floatValue] >=6.0){
                    
                    Ivar ivar=  class_getInstanceVariable([bview class],"_capacity");
                    
                    if(ivar){
                        
                        batteryLevel = ((int (*)(id, Ivar))object_getIvar)(bview, ivar);
                        
                        //这种方式也可以
                        
                        /*ptrdiff_t offset = ivar_getOffset(ivar);
                         
                         unsigned char *stuffBytes = (unsigned char *)(__bridge void *)bview;
                         
                         batteryLevel = * ((int *)(stuffBytes + offset));*/
                        
                        NSLog(@"电池电量:%d",batteryLevel);
                        
                        if (batteryLevel > 0 && batteryLevel <= 100) {
                            
                            return batteryLevel;
                            
                        } else {
                            
                            return 0;
                            
                        }
                        
                    }
                    
                }
                
            }
            
        }
        
    }
    
    return 0;
    
}

@end
