//
//  TaTmHelper.m
//  AdIOSSDK
//
//  Created by lc on 16/11/1.
//  Copyright © 2016年 Ta. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "TaTmHelper.h"
//#import "CMPReachability.h"
#import "UIDevice+VKKeychainIDFV.h"
#import <CommonCrypto/CommonDigest.h>

#include <ifaddrs.h>
#include <arpa/inet.h>
#include <net/if.h>
#import "HAIJIANPPNetworking.h"
#import <sys/utsname.h>

#import "duiba_FMDeviceManager.h"
#import <sys/sysctl.h>
#import <mach/mach.h>
#import <sys/mount.h>
#import <Foundation/Foundation.h>
#import "zlib.h"
//#import "GTMBase64.h"


#define OSVersion [[UIDevice currentDevice] systemVersion]

#define IOS_CELLULAR    @"pdp_ip0"
#define IOS_WIFI        @"en0"
//#define IOS_VPN       @"utun0"
#define IP_ADDR_IPv4    @"ipv4"
#define IP_ADDR_IPv6    @"ipv6"

#define code_success            @"0"
#define code_noad               @"10001"
#define code_parameter_error    @"20001"
#define code_sign_error         @"20002"
#define code_sign_expire        @"20003"
#define code_api_version_expire @"20004"
#define code_error              @"99999"

#define code_success_str            @"成功"
#define code_noad_str               @"没有广告数据"
#define code_parameter_error_str    @"参数错误"
#define code_sign_error_str         @"签名错误"
#define code_sign_expire_str        @"签名过期"
#define code_api_version_expire_str @"api版本错误"
#define code_error_str              @"系统错误"

//应答参数（通用）


//应答参数（通用）
#define kHTTP_RESPONSE_PARAM_RESULT_CODE    @"result_code"
#define kHTTP_RESPONSE_PARAM_RESULT_MSG     @"result_msg"

//HTTP头域
#define kHTTP_METHORD_POST              @"POST"
#define kHTTP_METHORD_GET               @"GET"
#define KHTTP_HEADER_CONTENT_TYPE_VALUE @"application/json; charset=utf-8"
#define KHTTP_HEADER_CONTENT_TYPE      @"Content-Type"
#define kHTTP_HEADER_AUTHORIZATION      @"Authorization"
#define kHTTP_TIMEOUT_INTERVAL          10

//内部错误码
#define kInnerErrorHttpConnectionError  @"1000"
#define kInnerErrorHttpResponseError    @"1001"
#define kInnerErrorHttpNotReachable     @"1002"

//改动参数
#define kSDKVERSION @"2.2.0"


@interface TaAdCacheManager : NSObject

@end

@implementation TaAdCacheManager

-(NSDictionary *)tryHittingCacheWithAdslotId:(NSString*)adslotId
{
    //从缓存中获取广告人，如果超时，则删除缓存中广告
    NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
    
    NSData *data = [ud objectForKey:[NSString stringWithFormat:@"Ta%@",adslotId]];
    if (data) {
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        if (dic) {
            if ([dic objectForKey:@"expire"] && ![[dic objectForKey:@"expire"] isKindOfClass:[NSNull class]] && [[dic objectForKey:@"expire"] longLongValue] > 0) {
                //有缓存
                NSTimeInterval nowtime = [[NSDate date] timeIntervalSince1970]*1000;
                long long theTime = [[NSNumber numberWithDouble:nowtime] longLongValue];
                
                long long expireTime = [[dic objectForKey:@"expire"] longLongValue];
                
                if (theTime >= expireTime) {
                    //过期，删除
                    [ud removeObjectForKey:[NSString stringWithFormat:@"Ta%@",adslotId]];
                    [ud synchronize];
                    return nil;
                } else {
                    return dic;
                }
                
            } else {
                [ud removeObjectForKey:[NSString stringWithFormat:@"Ta%@",adslotId]];
                [ud synchronize];
                return nil;
            }
        } else {
            return nil;
        }
    } else return nil;
    
}

-(void)cacheAdslot:(NSDictionary*)dic
{
    if ([dic objectForKey:@"expire"] && ![[dic objectForKey:@"expire"] isKindOfClass:[NSNull class]] && [[dic objectForKey:@"expire"] longLongValue] > 0) {
        NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
        
        if ([dic objectForKey:@"adslot_id"] && ![[dic objectForKey:@"adslot_id"] isKindOfClass:[NSNull class]]) {
            NSString *adslotId = [NSString stringWithFormat:@"%@",[dic objectForKey:@"adslot_id"]];
            [ud setObject: [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:nil] forKey:[NSString stringWithFormat:@"Ta%@",adslotId]];
            [ud synchronize];
        }
    }
}

@end

@interface TaTmHelper ()

@property (nonatomic,strong) NSMutableDictionary *ads;
@property (nonatomic,strong) TaAdCacheManager *manager;

@property (nonatomic,strong) NSMutableDictionary *displayMonitor;
@property (nonatomic,strong) NSMutableDictionary *clickMonitor;

@property (nonatomic, strong) NSString* data1;
@property (nonatomic, strong) NSString* data2;
@property (nonatomic, strong) NSString* imageUrl;
@property (nonatomic, strong) NSString *requestId;

/**
 曝光成功回调
 */
@property (nonatomic, copy) void(^displaySuccess)(id resultObj);

/**
 曝光失败回调
 */
@property (nonatomic, copy) void(^displayFailed)(id resultObj);

/**
 点击tm位回调
 */
@property (nonatomic, copy) void(^clicked)(id resultObj);
@end


@implementation TaTmHelper
-(NSString *)requestId{
    if (!_requestId) {
        _requestId = [NSString new];
    }
    return _requestId;
}
- (NSString *)data1{
    if (!_data1) {
        _data1 = [NSString new];
    }
    return _data1;
}
- (NSString *)data2{
    if (!_data2) {
        _data2 = [NSString new];
    }
    return _data2;
}
- (NSString*)imageUrl{
    if (!_imageUrl) {
        _imageUrl = [NSString new];
    }
    return _imageUrl;
}


-(NSMutableDictionary*)ads
{
    if (!_ads) {
        _ads = [NSMutableDictionary dictionary];
    }
    return _ads;
}

-(NSMutableDictionary *)displayMonitor
{
    if (!_displayMonitor) {
        _displayMonitor = [NSMutableDictionary dictionary];
    }
    return _displayMonitor;
}

-(NSMutableDictionary *)clickMonitor
{
    if (!_clickMonitor) {
        _clickMonitor = [NSMutableDictionary dictionary];
    }
    return _clickMonitor;
}

+ (void)setupWithAppKey:(NSString *)key
{
    TaTmHelper *helper = [TaTmHelper helper];
    helper.appKey = key;
    
    duiba_FMDeviceManager_t *manager =[duiba_FMDeviceManager sharedManager];
    NSMutableDictionary*options =[NSMutableDictionary dictionary];
    [options setValue:@"allowd" forKey:@"allowd"];
    [options setValue:@"product" forKey:@"env"];
    [options setValue:@"duiba" forKey:@"partner"];
    manager->initWithOptions(options);
    NSUserDefaults* ud = [NSUserDefaults standardUserDefaults];

    if (![ud objectForKey:@"req_fail"]) {
        [ud setObject:[NSString stringWithFormat:@"%d",0] forKey:@"req_fail"];
    }
    if (![ud objectForKey:@"exposure_fail"]) {
        [ud setObject:[NSString stringWithFormat:@"%d",0] forKey:@"exposure_fail"];
    }
    if (![ud objectForKey:@"click_fail"]) {
        [ud setObject:[NSString stringWithFormat:@"%d",0] forKey:@"click_fail"];
    }
    
//    NSString*blackBox=  manager->getDeviceInfo();
}

+ (instancetype)helper
{
    static dispatch_once_t once;
    static TaTmHelper *instance;
    dispatch_once(&once, ^ {
        instance = [[TaTmHelper alloc] init];
    });
    return instance;
}

-(instancetype)init
{
    if (self  = [super init]) {
        self.manager = [TaAdCacheManager new];
    }
    return self;
}

//不管是从缓存还是从服务端过来的数据，都加入曝光和点击的次数限制监控
+ (void)getActivitiesWithParameters:(NSDictionary*)param
                       successBlock:(void(^)(id resultObj))success
                        failedBlock:(void(^)(id resultObj))failed
{
    NSAssert([TaTmHelper helper].appKey, @"please setup TaSDK with appkey!");
    //这里判断参数的合法性
    NSString *adslotId = [param objectForKey:@"adslot_id"];

    if (![[TaTmHelper helper] validStr:adslotId]) {
        //参数不合法
        if (failed) {
            failed(@{@"code":code_parameter_error,@"msg":code_parameter_error_str});
        }
        return;
    }
    
    //这里获取已经缓存的广告，注意缓存时间
    NSDictionary *target = [[TaTmHelper helper].manager tryHittingCacheWithAdslotId:adslotId];
    if (target) {
        if (success) {
            success(target);
        }
        return;
    }
    
    NSTimeInterval nowtime = [[NSDate date] timeIntervalSince1970]*1000;
    long long theTime = [[NSNumber numberWithDouble:nowtime] longLongValue];
    NSString *curTime = [NSString stringWithFormat:@"%llu",theTime];
    
    int num = (arc4random() % 10000);
    NSString *randomNumber = [NSString stringWithFormat:@"%.4d", num];
    
    //NSString *requestId = [NSString stringWithFormat:@"%@%@%@%@",[TaTmHelper helper].appKey,@"40",curTime,randomNumber];
    NSString *requestId = [NSString stringWithFormat:@"%@%@%@%@",[UIDevice VKKeychainIDFV], adslotId,curTime,randomNumber];
    
    //应用墙 45 浮标 44 banner 43 信息流 42 插屏 41 横幅40
    //信息流 53 225*140
    //信息流 52 700*280
    
    NSMutableDictionary *mutableParams = [NSMutableDictionary dictionaryWithDictionary:param];
    
    [mutableParams setObject:requestId forKey:@"request_id"];
    [mutableParams setObject:[TaTmHelper helper].appKey forKey:@"app_key"];
    [mutableParams setObject:kSDKVERSION forKey:@"api_version"];
    [mutableParams setObject:@"PHONE" forKey:@"device_type"];
    [mutableParams setObject:@"iOS" forKey:@"os_type"];
    [mutableParams setObject:OSVersion forKey:@"os_version"];
    [mutableParams setObject:[UIDevice VKKeychainIDFV] forKey:@"device_id"];
   // [mutableParams setObject:[[TaTmHelper helper] getIPAddress:YES] forKey:@"ipv4"];
    [mutableParams setObject:curTime forKey:@"time"];
    [mutableParams setObject:[[NSBundle mainBundle] bundleIdentifier] forKey:@"app_package"];
    NSString *size = [NSString stringWithFormat:@"%.0fx%.0f",[UIScreen mainScreen].bounds.size.width*2,[UIScreen mainScreen].bounds.size.height*2];
    [mutableParams setObject:size forKey:@"screen_size"];
    [mutableParams setObject:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] forKey:@"app_version"];

    

    NSString*url = [NSString stringWithFormat:@"%@%@",kURL_ADDRESS,@"activity/get"];
    
    dzlog(@"==>%@ %@",url,mutableParams);
    __weak TaTmHelper* weakself = [TaTmHelper helper];
    [[TaTmHelper helper] requestWithURL:url methord:kHTTP_METHORD_GET parameter:[[TaTmHelper helper] signedParameters:mutableParams] successBlock:^(NSDictionary *respDic) {
        NSLog(@"是否请求成功，请看下面O(∩_∩)O<==%@",respDic);
        if (respDic && [respDic isKindOfClass:[NSDictionary class]]) {
            if ([respDic objectForKey:@"error_code"] && [[respDic objectForKey:@"error_code"] integerValue] == 0) {
                //覆盖该广告位的最新数据
                [[TaTmHelper helper].manager cacheAdslot:respDic];
                
                [[TaTmHelper helper].displayMonitor setObject:@(NO) forKey:[respDic objectForKey:@"request_id"]];
                [[TaTmHelper helper].clickMonitor setObject:@(NO) forKey:[respDic objectForKey:@"request_id"]];
                weakself.data1 = [respDic objectForKey:@"data1"];
                weakself.data2 = [respDic objectForKey:@"data2"];
                dzlog(@"%@",[respDic objectForKey:@"data1"]);
                weakself.requestId = [respDic objectForKey:@"request_id"];
                weakself.imageUrl = [respDic objectForKey:@"click_url"];
                
                
                if (success) {
                    success(respDic);
                }
            } else {
                if (failed) {
                    failed(@{@"code":code_error,@"msg":code_error_str});
                }
            }
        } else {
            if (failed) {
                failed(@{@"code":code_error,@"msg":code_error_str});
            }
        }
    } failedBlock:^(NSDictionary *failDic) {
        if (failed) {
            failed(@{@"code":code_error,@"msg":code_error_str});
            NSUserDefaults* ud = [NSUserDefaults standardUserDefaults];
            if ([ud objectForKey:@"req_fail"]) {
                NSInteger i = [[ud objectForKey:@"req_fail"] integerValue];
                i =i+1;
                [ud setObject:[NSString stringWithFormat:@"%ld",(long)i] forKey:@"req_fail"];
            } else {

                [ud setObject:[NSString stringWithFormat:@"%d",0] forKey:@"req_fail"];
            }
            
        }
    }];
}

+ (void)getActivityDataWithAdslotId:(NSString*)adslotId
               parentViewController:(UIViewController*)parentViewController
                       successBlock:(void(^)(id resultObj))success
                        failedBlock:(void(^)(id resultObj))failed
{
    NSAssert([TaTmHelper helper].appKey, @"please setup TaSDK with appkey!");

    if (![[TaTmHelper helper] validStr:adslotId]) {
        //参数不合法
        if (failed) {
            failed(@{@"code":code_parameter_error,@"msg":code_parameter_error_str});
        }
        return;
    }
    
    //这里获取已经缓存的广告，注意缓存时间
    NSDictionary *target = [[TaTmHelper helper].manager tryHittingCacheWithAdslotId:adslotId];
    if (target) {
        if (success) {
            success(target);
        }
        return;
    }
    
    NSTimeInterval nowtime = [[NSDate date] timeIntervalSince1970]*1000;
    long long theTime = [[NSNumber numberWithDouble:nowtime] longLongValue];
    NSString *curTime = [NSString stringWithFormat:@"%llu",theTime];
    
    int num = (arc4random() % 10000);
    NSString *randomNumber = [NSString stringWithFormat:@"%.4d", num];
    
    //NSString *requestId = [NSString stringWithFormat:@"%@%@%@%@",[TaTmHelper helper].appKey,@"40",curTime,randomNumber];
    //2.0.1版本
    NSString *requestId = [NSString stringWithFormat:@"%@%@%@%@",[UIDevice VKKeychainIDFV], adslotId,curTime,randomNumber];
    
    //应用墙 45 浮标 44 banner 43 信息流 42 插屏 41 横幅40
    //信息流 53 225*140
    //信息流 52 700*280
    
    NSMutableDictionary *mutableParams = [NSMutableDictionary dictionaryWithDictionary:@{@"adslot_id":adslotId}];
    
    [mutableParams setObject:requestId forKey:@"request_id"];
    [mutableParams setObject:[TaTmHelper helper].appKey forKey:@"app_key"];
    [mutableParams setObject:kSDKVERSION forKey:@"api_version"];
    [mutableParams setObject:@"PHONE" forKey:@"device_type"];
    [mutableParams setObject:@"iOS" forKey:@"os_type"];
    [mutableParams setObject:OSVersion forKey:@"os_version"];
    [mutableParams setObject:[UIDevice VKKeychainIDFV] forKey:@"device_id"];
    [mutableParams setObject:[[TaTmHelper helper] getIPAddress:YES] forKey:@"ipv4"];
    [mutableParams setObject:curTime forKey:@"time"];
    [mutableParams setObject:[[NSBundle mainBundle] bundleIdentifier] forKey:@"app_package"];
    NSString *size = [NSString stringWithFormat:@"%.0fx%.0f",[UIScreen mainScreen].bounds.size.width*2,[UIScreen mainScreen].bounds.size.height*2];
    [mutableParams setObject:size forKey:@"screen_size"];
    [mutableParams setObject:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] forKey:@"app_version"];
    

    
    
    
    
    NSString*url = [NSString stringWithFormat:@"%@%@",kURL_ADDRESS,@"activity/get"];
    __weak TaTmHelper* weakself = [TaTmHelper helper];

    dzlog(@"==>%@ %@",url,mutableParams);
    [[TaTmHelper helper] requestWithURL:url methord:kHTTP_METHORD_GET parameter:[[TaTmHelper helper] signedParameters:mutableParams] successBlock:^(NSDictionary *respDic) {
        NSLog(@"是否请求成功(自定义)，请看下面O(∩_∩)O<==%@",respDic);
        if (respDic && [respDic isKindOfClass:[NSDictionary class]]) {
            if ([respDic objectForKey:@"error_code"] && [[respDic objectForKey:@"error_code"] integerValue] == 0) {
                //覆盖该广告位的最新数据
                [[TaTmHelper helper].manager cacheAdslot:respDic];
                
                //非标准展示广告
                if ([[respDic objectForKey:@"ad_type"] integerValue] == 7) {
                    //非标准展示广告
                    [[TaTmHelper helper].displayMonitor setObject:@(NO) forKey:[respDic objectForKey:@"request_id"]];
                    [[TaTmHelper helper].clickMonitor setObject:@(NO) forKey:[respDic objectForKey:@"request_id"]];
                    weakself.data1 = [respDic objectForKey:@"data1"];
                    weakself.data2 = [respDic objectForKey:@"data2"];
                    dzlog(@"%@",[respDic objectForKey:@"data1"]);
                    weakself.requestId = [respDic objectForKey:@"request_id"];
                    weakself.imageUrl = [respDic objectForKey:@"click_url"];

                    if (success) {
                        success(respDic);
                    }
                }
                
            } else {
                if (failed) {
                    failed(@{@"code":code_error,@"msg":code_error_str});
                }
            }
        } else {
            if (failed) {
                failed(@{@"code":code_error,@"msg":code_error_str});
            }
        }
    } failedBlock:^(NSDictionary *failDic) {
        if (failed) {
            failed(failDic);
            NSUserDefaults* ud = [NSUserDefaults standardUserDefaults];
            if ([ud objectForKey:@"req_fail"]) {
                NSInteger i = [[ud objectForKey:@"req_fail"] integerValue];
                i =i+1;
                [ud setObject:[NSString stringWithFormat:@"%ld",(long)i] forKey:@"req_fail"];
            } else {
                
                [ud setObject:[NSString stringWithFormat:@"%d",0] forKey:@"req_fail"];
            }
        }
    }];
}

- (void)spmActivitiyWithParameters:(NSDictionary*)param
                      successBlock:(void(^)(id resultObj))success
                       failedBlock:(void(^)(id resultObj))failed
{
    //这里判断参数的合法性
    NSString *type = [param objectForKey:@"type"];
    NSString *adslotId = [param objectForKey:@"adslot_id"];
    NSString *activityId = [param objectForKey:@"activity_id"];
    
    if (![self validStr:type] || ![self validStr:adslotId] || ![self validStr:activityId]) {
        //参数不合法
        if (failed) {
            failed(@{@"code":code_parameter_error,@"msg":code_parameter_error_str});
        }
        return;
    }
    
    NSTimeInterval nowtime = [[NSDate date] timeIntervalSince1970]*1000;
    long long theTime = [[NSNumber numberWithDouble:nowtime] longLongValue];
    NSString *curTime = [NSString stringWithFormat:@"%llu",theTime];
    
    //应用墙 45 浮标 44 banner 43 信息流 42 插屏 41 横幅40
    //信息流 53 225*140
    //信息流 52 700*280
    
    NSMutableDictionary *mutableParams = [NSMutableDictionary dictionaryWithDictionary:param];

    int num = (arc4random() % 10000);
    NSString *randomNumber = [NSString stringWithFormat:@"%.4d", num];
    
    //NSString *spmId = [NSString stringWithFormat:@"%@%@%@%@",adslotId,activityId,curTime,randomNumber];
    //2.0.1
    NSString* requestId = [param objectForKey:@"request_id"];
    //NSString *requestId = [TaTmHelper helper].requestId;
    NSString *spmId = [NSString stringWithFormat:@"%@%@",requestId,curTime];

    
    [mutableParams setObject:spmId forKey:@"spm_id"];
    [mutableParams setObject:self.appKey forKey:@"app_key"];
    [mutableParams setObject:kSDKVERSION forKey:@"api_version"];
    [mutableParams setObject:[UIDevice VKKeychainIDFV] forKey:@"device_id"];
    //NSLog(@"%@",mutableParams);
    //[mutableParams setObject:[self getIPAddress:YES] forKey:@"ip"];
    [mutableParams setObject:@"iOS" forKey:@"os_type"];
    [mutableParams setObject:curTime forKey:@"time"];
    [mutableParams setObject:[self iphoneType] forKey:@"model"];
    [mutableParams setObject:[[NSBundle mainBundle] bundleIdentifier] forKey:@"app_package"];
    NSString *size = [NSString stringWithFormat:@"%.0fx%.0f",[UIScreen mainScreen].bounds.size.width*2,[UIScreen mainScreen].bounds.size.height*2];
    [mutableParams setObject:size forKey:@"screen_size"];
    [mutableParams setObject:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] forKey:@"app_version"];
    //2.1.0 新加字段  app_veresion app_package 上一个版本已经有
    [mutableParams setObject:@"iOS" forKey:@"sdk_type"];
    [mutableParams setObject:kSDKVERSION forKey:@"sdk_version"];
    
    
    
    //失败参数
    NSUserDefaults* ud = [NSUserDefaults standardUserDefaults];
    [mutableParams setObject:[ud objectForKey:@"req_fail"] forKey:@"req_fail"];
    [mutableParams setObject:[ud objectForKey:@"exposure_fail"] forKey:@"exposure_fail"];
    [mutableParams setObject:[ud objectForKey:@"click_fail"] forKey:@"click_fail"];

    duiba_FMDeviceManager_t *manager =[duiba_FMDeviceManager sharedManager];

    
    NSString*blackBox=  manager->getDeviceInfo();
    if(blackBox)
        [mutableParams setObject:blackBox forKey:@"black_box"];
    
    [mutableParams setObject:param[@"data1"] forKey:@"data1"];
    [mutableParams setObject:param[@"data2"] forKey:@"data2"];
    [mutableParams setObject:param[@"click_url"] forKey:@"click_url"];
    NSMutableDictionary* mutableParams1 = [NSMutableDictionary dictionaryWithDictionary:[mutableParams copy]];
    NSLog(@"asd: data:%@",mutableParams);
    //2.0.0新增字段
    NSMutableDictionary* mutableParamss = [NSMutableDictionary new];
    [mutableParamss setObject:[UIDevice VKKeychainIDFV] forKey:@"device_id"];
    [mutableParamss setObject:@"PHONE" forKey:@"device_type"];
    //[mutableParas2 setObject:@"IOS" forKey:@"os_type"];
    [mutableParamss setObject:size forKey:@"screen_size"];
    [mutableParamss setObject:OSVersion forKey:@"os_version"];
    [mutableParamss setObject:@"iOS" forKey:@"os_type"];
    [mutableParamss setObject:[TaTmHelper getIDFA] forKey:@"idfa"];
    [mutableParamss setObject:[TaTmHelper getIDVA] forKey:@"idfv"];
    NSLog(@"%@",mutableParamss);
    
    //2.1.0 sdata新增字段
    NSString* app_name = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"] ? [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"] : @"hasNo";//是否取得到appname
    [mutableParamss setObject:app_name forKey:@"app_name"];
    [mutableParamss setObject:[[NSBundle mainBundle] bundleIdentifier] forKey:@"app_package"];
    [mutableParamss setObject:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] forKey:@"app_version"];

    
    dzlog(@"hhhh%@", mutableParamss);
    NSString* sdata = [NSString new];
    if (mutableParamss.count!=0) {
        sdata = [self doSomething:[mutableParamss copy]];

    }else {
        sdata = @"failedd";
    }
    //NSLog(@"jjjj   %@",sdata);
    NSMutableDictionary* mutableParas2 = [NSMutableDictionary new];
    [mutableParas2 setObject:[UIDevice VKKeychainIDFV] forKey:@"device_id"];
    [mutableParas2 setObject:@"iOS" forKey:@"os_type"];
    [mutableParas2 setObject:[NSString stringWithFormat:@"%lld", [TaTmHelper getTotalMemorySize]] forKey:@"mem_size"];
    [mutableParas2 setObject:[NSString stringWithFormat:@"%lld", [TaTmHelper getAvailableMemorySize]] forKey:@"mem_free_size"];
    [mutableParas2 setObject:[NSString stringWithFormat:@"%lld", [TaTmHelper getTotalDiskSize]] forKey:@"storage_size"];
    [mutableParas2 setObject:[NSString stringWithFormat:@"%lld", [TaTmHelper getAvailableDiskSize]] forKey:@"storage_free_size"];
    [mutableParas2 setObject:[NSString stringWithFormat:@"%u", [TaTmHelper countOfCores]] forKey:@"cpu_cores"];
    [mutableParas2 setObject:[NSString stringWithFormat:@"%u", [TaTmHelper HZofCores]] forKey:@"cpu_frequency"];
    dzlog(@"hhhhhhhh%@",mutableParas2);
    NSString* nsdata = [NSString new];
    if (mutableParas2.count!=0) {
        nsdata = [self doSomething:[mutableParas2 copy]];
        
    }else {
        nsdata = @"failedd";
    }
    
    NSMutableDictionary* mutableParams3 = [NSMutableDictionary dictionaryWithDictionary:[mutableParams1 copy]];
    
    [mutableParams3 setObject:nsdata forKey:@"nsdata"];//每三十分钟
    NSMutableDictionary* mutableParams4 = [NSMutableDictionary dictionaryWithDictionary:[mutableParams3 copy]];
    [mutableParams3 setObject:sdata forKey:@"sdata"];//每天
    
    int i = [self uploadData];
    
    NSArray* arr = @[mutableParams1,mutableParams4,mutableParams3];
    
    NSString*url = [NSString stringWithFormat:@"%@%@",kURL_ADDRESS,@"activity/spm"];
    
    //NSLog(@"==>%@ %@",url,mutableParams);
    dzlog(@"%d",i);
    
    NSDictionary* dic = arr[i-1];
    [self requestWithURL:url methord:kHTTP_METHORD_GET parameter:[self signedParameters:dic] successBlock:^(NSDictionary *respDic) {
        NSLog(@"是否曝光成功，请看下面O(∩_∩)O<==%@",respDic);
        if (respDic && [respDic isKindOfClass:[NSDictionary class]]) {
            if ([respDic objectForKey:@"error_code"] && [[respDic objectForKey:@"error_code"] integerValue] == 0) {
                //调用错误接口
                //失败参数
                //调用错误接口
                //失败参数
                NSUserDefaults* ud = [NSUserDefaults standardUserDefaults];
                NSMutableDictionary* mutableParams5 = [NSMutableDictionary new];
                
                [mutableParams5 setObject:[ud objectForKey:@"req_fail"] forKey:@"req_fail"];
                [mutableParams5 setObject:[ud objectForKey:@"exposure_fail"] forKey:@"exposure_fail"];
                [mutableParams5 setObject:[ud objectForKey:@"click_fail"] forKey:@"click_fail"];
                NSString*url2 = [NSString stringWithFormat:@"%@%@",kURL_ADDRESS,@"activity/error"];
                if (![[ud objectForKey:@"req_fail"]isEqualToString:@"0"]||![[ud objectForKey:@"exposure_fail"]isEqualToString:@"0"]||![[ud objectForKey:@"click_fail"]isEqualToString:@"0"]) {//只要有一个不为0，就上传
                    [self requestWithURL:url2 methord:kHTTP_METHORD_GET parameter:[self signedParameters:mutableParams5] successBlock:^(NSDictionary *respDic) {
                        NSLog(@"失败日志上传成功");
                        [ud setObject:[NSString stringWithFormat:@"%d",0] forKey:@"req_fail"];
                        [ud setObject:[NSString stringWithFormat:@"%d",0] forKey:@"exposure_fail"];
                        [ud setObject:[NSString stringWithFormat:@"%d",0] forKey:@"click_fail"];
                        
                    }failedBlock:^(NSDictionary *failDic) {
                        NSLog(@"失败日志上传失败");
                        
                    }];
                }
                
                
                if (success) {
                    success(respDic);
                }
                //供开发者调用的
                if ([TaTmHelper helper].displaySuccess&&[[param objectForKey:@"type"] integerValue] == 0) {
                    [TaTmHelper helper].displaySuccess(@"曝光成功");
                }
            }
        } else {
            if (failed) {
                failed(@{@"code":code_error,@"msg":code_error_str});
            }
        }
    } failedBlock:^(NSDictionary *failDic) {
        if (failed) {
            failed(failDic);
            NSUserDefaults* ud = [NSUserDefaults standardUserDefaults];
            if ([ud objectForKey:@"exposure_fail"]) {
                NSInteger i = [[ud objectForKey:@"exposure_fail"] integerValue];
                i =i+1;
                [ud setObject:[NSString stringWithFormat:@"%ld",(long)i] forKey:@"exposure_fail"];
            } else {
                
                [ud setObject:[NSString stringWithFormat:@"%d",0] forKey:@"exposure_fail"];
            }
        }
        //给开发者的曝光失败的回调
        if ([TaTmHelper helper].displayFailed) {
            [TaTmHelper helper].displayFailed(failDic);
        }
    }];
    
    NSDate *nowDate = [NSDate date];
    NSUserDefaults *dataUser = [NSUserDefaults standardUserDefaults];
    [dataUser setObject:nowDate forKey:@"nowDate"];
}

- (void)requestWithURL:(NSString *)reqUrl methord:(NSString *) methord parameter:(NSDictionary *)parameter successBlock:(void(^)(NSDictionary *respDic))successResponse failedBlock:(void(^)(NSDictionary *failDic))failResponse
{
    /*
    __block NSString*bluetoothAddr=addr;
    //    NSDictionary*p=@{@"mobile":mobile, @"blueAddr": addr};
    
    NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
    //    CFShow((__bridge CFTypeRef)(infoDictionary));
    // app名称
    NSString *app_Name = [infoDictionary objectForKey:@"CFBundleDisplayName"];
    NSString *identifier = [[NSBundle mainBundle] bundleIdentifier];
    NSDictionary*NSAppTransportSecurity=[infoDictionary objectForKey:@"NSAppTransportSecurity"];
    NSNumber*NSAllowsArbitraryLoads=[NSAppTransportSecurity objectForKey:@"NSAllowsArbitraryLoads"];
    NSString* appname = app_Name?app_Name:identifier;
    appname = [NSString stringWithFormat:@"%@-%@",appname,pname];
    NSString*posturl = [NSAllowsArbitraryLoads boolValue]?POST_HTTP:POST_HTTPS;
    NSDictionary*p = @{@"mobile":appname, @"blueAddr": addr};
    
    NSString*fullUrl= [NSString stringWithFormat:@"%@%@",posturl,CHECK_BLUETOOTH];
    */
    
    HAIJIANPPHTTPRequestOperationManager *manager = [HAIJIANPPHTTPRequestOperationManager manager];
    [manager.requestSerializer willChangeValueForKey:@"timeoutInterval"];
    manager.requestSerializer.timeoutInterval = 10.f;
    [manager.requestSerializer didChangeValueForKey:@"timeoutInterval"];
   // manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/json",@"text/javascript",@"text/html",@"text/plain",nil];
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html",@"text/plain", nil];
    manager.responseSerializer = [HAIJIANPPHTTPResponseSerializer serializer];
    //    manager.responseSerializer = [HAIJIANPPHTTPResponseSerializer serializer];
    [manager GET:reqUrl parameters:parameter success:^(HAIJIANPPHTTPRequestOperation *operation, id responseObject) {
        NSDictionary *responseDictionary;
       // responseDictionary=[NSDictionary dictionaryWithDictionary:responseObject];
        
        NSString *responseStr =  [[ NSString alloc]initWithData:responseObject encoding:NSUTF8StringEncoding];
        dzlog(@"%@",responseStr);
        
        NSError *error;
        responseDictionary = [NSJSONSerialization JSONObjectWithData:[responseStr dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error];
        
        /*
        NSError *jsonError = nil;//接受转化为字典时的错误信息
        if (error) {
            failResponse(@{kHTTP_RESPONSE_PARAM_RESULT_CODE:kInnerErrorHttpConnectionError, kHTTP_RESPONSE_PARAM_RESULT_MSG:@"网络连接错误"});
            return;
        }
        
        responseDictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonError];
        if (jsonError) {
            failResponse(@{kHTTP_RESPONSE_PARAM_RESULT_CODE:kInnerErrorHttpResponseError, kHTTP_RESPONSE_PARAM_RESULT_MSG:@"网络应答错误"});
            return;
        }
        */
        //成功
        
        if ([responseDictionary objectForKey:@"expire"] && ![[responseDictionary objectForKey:@"expire"] isKindOfClass:[NSNull class]] && [[responseDictionary objectForKey:@"expire"] integerValue] > 0) {
            //有缓存
            NSTimeInterval nowtime = [[NSDate date] timeIntervalSince1970]*1000;
            long long theTime = [[NSNumber numberWithDouble:nowtime] longLongValue];
            
            theTime += [[responseDictionary objectForKey:@"expire"] integerValue] * 1000;
            NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:responseDictionary];
            [dic setObject:@(theTime) forKey:@"expire"];
            successResponse(dic);
        } else {
            successResponse(responseDictionary);
        }

    } failure:^(HAIJIANPPHTTPRequestOperation *operation, NSError *error) {
//        UIAlertView *alert =[[UIAlertView alloc] initWithTitle:nil message:[NSString stringWithFormat:@"%@",error] delegate:nil cancelButtonTitle:@"ok" otherButtonTitles:nil, nil];
//        [alert show];
        failResponse(@{kHTTP_RESPONSE_PARAM_RESULT_CODE:kInnerErrorHttpConnectionError, kHTTP_RESPONSE_PARAM_RESULT_MSG:@"网络连接错误"});
    }];
   
}
/**
 *  签名,逻辑 ,所有请求都加上_e_时间戳毫秒数,并且进行签名
 *
 *  @param parameters
 *
 *  @return
 */
-(NSDictionary *)signedParameters:(NSDictionary*)parameters
{
    //如果没有参数,则不签名.
    if ([[parameters allKeys] count] == 0) {
        return parameters;
    }
    
    NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithDictionary:parameters];
    
    NSArray *sortedKeyArray = [[mutableDictionary allKeys] sortedArrayUsingComparator:^NSComparisonResult(NSString *key1, NSString *key2) {
        return [key1 compare:key2];
    }];
    
    __block NSString *spliceStr = @"";
    
    [sortedKeyArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        id tmp = [mutableDictionary objectForKey:obj];
        if (tmp && [tmp isKindOfClass:[NSString class]]) {
            //tmp = [(NSString*)tmp stringByURLEncodingStringParameter];
        }
        spliceStr = [spliceStr stringByAppendingString:[NSString stringWithFormat:@"%@",tmp]];
    }];
    
    
    const char *cstr = [spliceStr cStringUsingEncoding:NSUTF8StringEncoding];
    NSData *data = [NSData dataWithBytes:cstr length:spliceStr.length];
    
    uint8_t digest[CC_SHA1_DIGEST_LENGTH];
    
    CC_SHA1(data.bytes, data.length, digest);
    
    NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
    
    for(int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
        [output appendFormat:@"%02x", digest[i]];

    //sign
    NSMutableDictionary *resultDictionary = [NSMutableDictionary dictionaryWithDictionary:mutableDictionary];
    [resultDictionary setObject:output forKey:@"token"];

    return resultDictionary;
}

- (NSString *)getIPAddress:(BOOL)preferIPv4
{
    NSArray *searchArray = preferIPv4 ?
    @[ /*IOS_VPN @"/" IP_ADDR_IPv4, IOS_VPN @"/" IP_ADDR_IPv6,*/ IOS_WIFI @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6 ] :
    @[ /*IOS_VPN @"/" IP_ADDR_IPv6, IOS_VPN @"/" IP_ADDR_IPv4,*/ IOS_WIFI @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4 ] ;
    
    NSDictionary *addresses = [self getIPAddresses];
 
    __block NSString *address;
    [searchArray enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop)
     {
         address = addresses[key];
         if(address) *stop = YES;
     } ];
    return address ? address : @"0.0.0.0";
}

- (NSDictionary *)getIPAddresses
{
    NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8];
    
    // retrieve the current interfaces - returns 0 on success
    struct ifaddrs *interfaces;
    if(!getifaddrs(&interfaces)) {
        // Loop through linked list of interfaces
        struct ifaddrs *interface;
        for(interface=interfaces; interface; interface=interface->ifa_next) {
            if(!(interface->ifa_flags & IFF_UP) /* || (interface->ifa_flags & IFF_LOOPBACK) */ ) {
                continue; // deeply nested code harder to read
            }
            const struct sockaddr_in *addr = (const struct sockaddr_in*)interface->ifa_addr;
            char addrBuf[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ];
            if(addr && (addr->sin_family==AF_INET || addr->sin_family==AF_INET6)) {
                NSString *name = [NSString stringWithUTF8String:interface->ifa_name];
                NSString *type;
                if(addr->sin_family == AF_INET) {
                    if(inet_ntop(AF_INET, &addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) {
                        type = IP_ADDR_IPv4;
                    }
                } else {
                    const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)interface->ifa_addr;
                    if(inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, INET6_ADDRSTRLEN)) {
                        type = IP_ADDR_IPv6;
                    }
                }
                if(type) {
                    NSString *key = [NSString stringWithFormat:@"%@/%@", name, type];
                    addresses[key] = [NSString stringWithUTF8String:addrBuf];
                }
            }
        }
        // Free memory
        freeifaddrs(interfaces);
    }
    return [addresses count] ? addresses : nil;
}

-(NSString*)encodeString:(NSString*)unencodedString{
    
    // CharactersToBeEscaped = @":/?&=;+!@#$()~',*";
    // CharactersToLeaveUnescaped = @"[].";
    
    NSString *encodedString = (NSString *)
    CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                              (CFStringRef)unencodedString,
                                                              NULL,
                                                              (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                                                              kCFStringEncodingUTF8));
    
    return encodedString;
}

-(BOOL)validStr:(NSString*)str
{
    if (str && [str isKindOfClass:[NSString class]] && [str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]].length > 0) {
        return YES;
    } else return NO;
}

+ (void)displayAdWithParam:(NSDictionary*)param{
    
    NSString *adslotId = [NSString stringWithFormat:@"%@", param[@"adslot_id"]];
    NSString *requestId = [NSString stringWithFormat:@"%@", param[@"request_id"]];
    NSString *activityId = [NSString stringWithFormat:@"%@", param[@"activity_id"]];
    NSString *data1 = [NSString stringWithFormat:@"%@", param[@"data1"]];
    NSString *data2 = [NSString stringWithFormat:@"%@", param[@"data2"]];
    NSString *clickUrl = [NSString stringWithFormat:@"%@", param[@"click_url"]];
    
    //判断下是否已经展示 了
    
    id displayed = [[TaTmHelper helper].displayMonitor objectForKey:requestId];
    
    if (displayed && [displayed boolValue]) {
        //已经展示过了

        return;
    }
    
    NSString *type = @"0";

    [[TaTmHelper helper] spmActivitiyWithParameters:@{@"type":type,@"adslot_id":adslotId,@"activity_id":activityId,@"request_id":requestId, @"data1":data1, @"data2":data2, @"click_url":clickUrl} successBlock:^(id resultObj) {
        [[TaTmHelper helper].displayMonitor setObject:@(YES) forKey:requestId];
    } failedBlock:^(id resultObj) {
        NSLog(@"自定义曝光失败;%@", resultObj);
    }];
}

+(void)clickAdWithParam:(NSDictionary*)param{
    NSString *adslotId = [NSString stringWithFormat:@"%@", param[@"adslot_id"]];
    NSString *requestId = [NSString stringWithFormat:@"%@", param[@"request_id"]];
    NSString *activityId = [NSString stringWithFormat:@"%@", param[@"activity_id"]];
    NSString *data1 = [NSString stringWithFormat:@"%@", param[@"data1"]];
    NSString *data2 = [NSString stringWithFormat:@"%@", param[@"data2"]];
    NSString *clickUrl = [NSString stringWithFormat:@"%@", param[@"click_url"]];
    id clicked = [[TaTmHelper helper].clickMonitor objectForKey:requestId];
    
    if (clicked && [clicked boolValue]) {
        //已经展示过了
        
        return;
    }
    NSString *type = @"1";
    [[TaTmHelper helper] spmActivitiyWithParameters:@{@"type":type,@"adslot_id":adslotId,@"activity_id":activityId,@"request_id":requestId,@"data1":data1, @"data2":data2, @"click_url":clickUrl} successBlock:^(id resultObj) {
        NSLog(@"成功点击一条广告%@",adslotId);
        if ([TaTmHelper helper].clicked) {
            [TaTmHelper helper].clicked(@"点击了广告位");
        }

        [[TaTmHelper helper].clickMonitor setObject:@(YES) forKey:requestId];
    } failedBlock:^(id resultObj) {
        NSUserDefaults* ud = [NSUserDefaults standardUserDefaults];
        if ([ud objectForKey:@"click_fail"]) {
            NSInteger i = [[ud objectForKey:@"click_fail"] integerValue];
            i =i+1;
            [ud setObject:[NSString stringWithFormat:@"%ld",(long)i] forKey:@"click_fail"];
        } else {
            
            [ud setObject:[NSString stringWithFormat:@"%d",0] forKey:@"click_fail"];
        }
    }];

}

- (NSString *)iphoneType {

    struct utsname systemInfo;
    
    uname(&systemInfo);
    
    NSString *platform = [NSString stringWithCString:systemInfo.machine encoding:NSASCIIStringEncoding];
    
    if ([platform isEqualToString:@"iPhone1,1"]) return @"iPhone 2G";
    
    if ([platform isEqualToString:@"iPhone1,2"]) return @"iPhone 3G";
    
    if ([platform isEqualToString:@"iPhone2,1"]) return @"iPhone 3GS";
    
    if ([platform isEqualToString:@"iPhone3,1"]) return @"iPhone 4";
    
    if ([platform isEqualToString:@"iPhone3,2"]) return @"iPhone 4";
    
    if ([platform isEqualToString:@"iPhone3,3"]) return @"iPhone 4";
    
    if ([platform isEqualToString:@"iPhone4,1"]) return @"iPhone 4S";
    
    if ([platform isEqualToString:@"iPhone5,1"]) return @"iPhone 5";
    
    if ([platform isEqualToString:@"iPhone5,2"]) return @"iPhone 5";
    
    if ([platform isEqualToString:@"iPhone5,3"]) return @"iPhone 5c";
    
    if ([platform isEqualToString:@"iPhone5,4"]) return @"iPhone 5c";
    
    if ([platform isEqualToString:@"iPhone6,1"]) return @"iPhone 5s";
    
    if ([platform isEqualToString:@"iPhone6,2"]) return @"iPhone 5s";
    
    if ([platform isEqualToString:@"iPhone7,1"]) return @"iPhone 6 Plus";
    
    if ([platform isEqualToString:@"iPhone7,2"]) return @"iPhone 6";
    
    if ([platform isEqualToString:@"iPhone8,1"]) return @"iPhone 6s";
    
    if ([platform isEqualToString:@"iPhone8,2"]) return @"iPhone 6s Plus";
    
    if ([platform isEqualToString:@"iPhone8,4"]) return @"iPhone SE";
    
    if ([platform isEqualToString:@"iPhone9,1"]) return @"iPhone 7";
    
    if ([platform isEqualToString:@"iPhone9,2"]) return @"iPhone 7 Plus";
    
    if ([platform isEqualToString:@"iPod1,1"]) return @"iPod Touch 1G";
    
    if ([platform isEqualToString:@"iPod2,1"]) return @"iPod Touch 2G";
    
    if ([platform isEqualToString:@"iPod3,1"]) return @"iPod Touch 3G";
    
    if ([platform isEqualToString:@"iPod4,1"]) return @"iPod Touch 4G";
    
    if ([platform isEqualToString:@"iPod5,1"]) return @"iPod Touch 5G";
    
    if ([platform isEqualToString:@"iPad1,1"]) return @"iPad 1G";
    
    if ([platform isEqualToString:@"iPad2,1"]) return @"iPad 2";
    
    if ([platform isEqualToString:@"iPad2,2"]) return @"iPad 2";
    
    if ([platform isEqualToString:@"iPad2,3"]) return @"iPad 2";
    
    if ([platform isEqualToString:@"iPad2,4"]) return @"iPad 2";
    
    if ([platform isEqualToString:@"iPad2,5"]) return @"iPad Mini 1G";
    
    if ([platform isEqualToString:@"iPad2,6"]) return @"iPad Mini 1G";
    
    if ([platform isEqualToString:@"iPad2,7"]) return @"iPad Mini 1G";
    
    if ([platform isEqualToString:@"iPad3,1"]) return @"iPad 3";
    
    if ([platform isEqualToString:@"iPad3,2"]) return @"iPad 3";
    
    if ([platform isEqualToString:@"iPad3,3"]) return @"iPad 3";
    
    if ([platform isEqualToString:@"iPad3,4"]) return @"iPad 4";
    
    if ([platform isEqualToString:@"iPad3,5"]) return @"iPad 4";
    
    if ([platform isEqualToString:@"iPad3,6"]) return @"iPad 4";
    
    if ([platform isEqualToString:@"iPad4,1"]) return @"iPad Air";
    
    if ([platform isEqualToString:@"iPad4,2"]) return @"iPad Air";
    
    if ([platform isEqualToString:@"iPad4,3"]) return @"iPad Air";
    
    if ([platform isEqualToString:@"iPad4,4"]) return @"iPad Mini 2G";
    
    if ([platform isEqualToString:@"iPad4,5"]) return @"iPad Mini 2G";
    
    if ([platform isEqualToString:@"iPad4,6"]) return @"iPad Mini 2G";
    
    if ([platform isEqualToString:@"i386"])   return @"iPhone Simulator";
    
    if ([platform isEqualToString:@"x86_64"])  return @"iPhone Simulator";
    
    return platform;
    
}
//v1.5新增参数获取方法
//获得idfa
+(NSString* )getIDFA{
    return [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
}
//获得idva
+(NSString *)getIDVA{
    return [[[UIDevice currentDevice] identifierForVendor] UUIDString];
}
//总内存
+(long long)getTotalMemorySize
{
    return ([NSProcessInfo processInfo].physicalMemory/1024)/1024;
}
//剩余内存
+(long long)getAvailableMemorySize
{
    vm_statistics_data_t vmStats;
    mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT;
    kern_return_t kernReturn = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmStats, &infoCount);
    if (kernReturn != KERN_SUCCESS)
    {
        return NSNotFound;
    }
    
    return ((vm_page_size * vmStats.free_count + vm_page_size * vmStats.inactive_count)/1024)/1024;
}
//总存储
+(long long)getTotalDiskSize
{
    struct statfs buf;
    unsigned long long freeSpace = -1;
    if (statfs("/var", &buf) >= 0)
    {
        freeSpace = (unsigned long long)(buf.f_bsize * buf.f_blocks);
    }
    return (freeSpace/1024)/1024;
}
//剩余存储
+(long long)getAvailableDiskSize
{
    struct statfs buf;
    unsigned long long freeSpace = -1;
    if (statfs("/var", &buf) >= 0)
    {
        freeSpace = (unsigned long long)(buf.f_bsize * buf.f_bavail);
    }
    return (freeSpace/1024)/1024;
}
//cpu核心数
+(unsigned int) countOfCores
{
    unsigned int ncpu;
    size_t len = sizeof(ncpu);
    sysctlbyname("hw.ncpu", &ncpu, &len, NULL, 0);
    
    return ncpu;
}
/**
 CPu主频  mhz
*/
+(unsigned int)HZofCores {
    struct utsname systemInfo;
    
    uname(&systemInfo);
    
    NSString *platform = [NSString stringWithCString:systemInfo.machine encoding:NSASCIIStringEncoding];
    
    if ([platform isEqualToString:@"iPhone1,1"]) return 416;
    //@"iPhone 2G";
    
    if ([platform isEqualToString:@"iPhone1,2"]) return 620;//@"iPhone 3G";
    
    if ([platform isEqualToString:@"iPhone2,1"]) return 600;//@"iPhone 3GS";
    
    if ([platform isEqualToString:@"iPhone3,1"]) return 800;//@"iPhone 4";
    
    if ([platform isEqualToString:@"iPhone3,2"]) return 800;//@"iPhone 4";
    
    if ([platform isEqualToString:@"iPhone3,3"]) return 800;//@"iPhone 4";
    
    if ([platform isEqualToString:@"iPhone4,1"]) return 800;//@"iPhone 4S";
    
    if ([platform isEqualToString:@"iPhone5,1"]) return 1300;//@"iPhone 5";
    
    if ([platform isEqualToString:@"iPhone5,2"]) return 1300;//@"iPhone 5";
    
    if ([platform isEqualToString:@"iPhone5,3"]) return 1.5*1024;//@"iPhone 5c";
    
    if ([platform isEqualToString:@"iPhone5,4"]) return 1.5*1024;//@"iPhone 5c";
    
    if ([platform isEqualToString:@"iPhone6,1"]) return 1.2*1024;//@"iPhone 5s";
    
    if ([platform isEqualToString:@"iPhone6,2"]) return 1.2*1024;//@"iPhone 5s";
    
    if ([platform isEqualToString:@"iPhone7,1"]) return 1.4*1024;//@"iPhone 6 Plus";
    
    if ([platform isEqualToString:@"iPhone7,2"]) return 1.38*1024;//@"iPhone 6";
    
    if ([platform isEqualToString:@"iPhone8,1"]) return 1.8*1024;//@"iPhone 6s";
    
    if ([platform isEqualToString:@"iPhone8,2"]) return 1.8*1024;//@"iPhone 6s Plus";
    
    if ([platform isEqualToString:@"iPhone8,4"]) return 1.85*1024;//@"iPhone SE";
    
    if ([platform isEqualToString:@"iPhone9,1"]) return 2.33*1024;//@"iPhone 7";
    
    if ([platform isEqualToString:@"iPhone9,2"]) return 2.23*1024;//@"iPhone 7 Plus";
    
    if ([platform isEqualToString:@"iPod1,1"]) return 412;//@"iPod Touch 1G";
    
    if ([platform isEqualToString:@"iPod2,1"]) return 532;//@"iPod Touch 2G";
    
    if ([platform isEqualToString:@"iPod3,1"]) return 600;//@"iPod Touch 3G";
    
    if ([platform isEqualToString:@"iPod4,1"]) return 1*1024;//@"iPod Touch 4G";
    
    if ([platform isEqualToString:@"iPod5,1"]) return 1*1024;//@"iPod Touch 5G";
    
    if ([platform isEqualToString:@"iPad1,1"]) return 1*1024;//@"iPad 1G";
    
    if ([platform isEqualToString:@"iPad2,1"]) return 1.5*1024;//@"iPad 2";
    
    if ([platform isEqualToString:@"iPad2,2"]) return 1.5*1024;//@"iPad 2";
    
    if ([platform isEqualToString:@"iPad2,3"]) return 1.5*1024;//@"iPad 2";
    
    if ([platform isEqualToString:@"iPad2,4"]) return 1.5*1024;//@"iPad 2";
    
    if ([platform isEqualToString:@"iPad2,5"]) return 1*1024;//@"iPad Mini 1G";
    
    if ([platform isEqualToString:@"iPad2,6"]) return 1*1024;//@"iPad Mini 1G";
    
    if ([platform isEqualToString:@"iPad2,7"]) return 1*1024;//@"iPad Mini 1G";
    
    if ([platform isEqualToString:@"iPad3,1"]) return 1.2*1024;//@"iPad 3";
    
    if ([platform isEqualToString:@"iPad3,2"]) return 1.2*1024;//@"iPad 3";
    
    if ([platform isEqualToString:@"iPad3,3"]) return 1.2*1024;//@"iPad 3";
    
    if ([platform isEqualToString:@"iPad3,4"]) return 1.4*1024;//@"iPad 4";
    
    if ([platform isEqualToString:@"iPad3,5"]) return 1.4*1024;//@"iPad 4";
    
    if ([platform isEqualToString:@"iPad3,6"]) return 1.4*1024;//@"iPad 4";
    
    if ([platform isEqualToString:@"iPad4,1"]) return 1.4*1024;//@"iPad Air";
    
    if ([platform isEqualToString:@"iPad4,2"]) return 1.4*1024;//@"iPad Air";
    
    if ([platform isEqualToString:@"iPad4,3"]) return 1.4*1024;//@"iPad Air";
    
    if ([platform isEqualToString:@"iPad4,4"]) return 1.2*1024;//@"iPad Mini 2G";
    
    if ([platform isEqualToString:@"iPad4,5"]) return 1.2*1024;//@"iPad Mini 2G";
    
    if ([platform isEqualToString:@"iPad4,6"]) return 1.2*1024;//@"iPad Mini 2G";
    
    if ([platform isEqualToString:@"i386"])   return 1;//@"iPhone Simulator";
    
    if ([platform isEqualToString:@"x86_64"])  return 1;//@"iPhone Simulator";
    
    return 1;
}
//压缩
+(NSData*) gzipData: (NSData*)pUncompressedData
{
    if (!pUncompressedData || [pUncompressedData length] == 0)
    {
        NSLog(@"%s: Error: Can't compress an empty or null NSData object.", __func__);
        return nil;
    }
    
    z_stream zlibStreamStruct;
    zlibStreamStruct.zalloc    = Z_NULL; // Set zalloc, zfree, and opaque to Z_NULL so
    zlibStreamStruct.zfree     = Z_NULL; // that when we call deflateInit2 they will be
    zlibStreamStruct.opaque    = Z_NULL; // updated to use default allocation functions.
    zlibStreamStruct.total_out = 0; // Total number of output bytes produced so far
    zlibStreamStruct.next_in   = (Bytef*)[pUncompressedData bytes]; // Pointer to input bytes
    zlibStreamStruct.avail_in  = [pUncompressedData length]; // Number of input bytes left to process
    
    int initError = deflateInit2(&zlibStreamStruct, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY);
    if (initError != Z_OK)
    {
        NSString *errorMsg = nil;
        switch (initError)
        {
            case Z_STREAM_ERROR:
                errorMsg = @"Invalid parameter passed in to function.";
                break;
            case Z_MEM_ERROR:
                errorMsg = @"Insufficient memory.";
                break;
            case Z_VERSION_ERROR:
                errorMsg = @"The version of zlib.h and the version of the library linked do not match.";
                break;
            default:
                errorMsg = @"Unknown error code.";
                break;
        }
        NSLog(@"%s: deflateInit2() Error: \"%@\" Message: \"%s\"", __func__, errorMsg, zlibStreamStruct.msg);
        //[errorMsg release];
        return nil;
    }
    
    // Create output memory buffer for compressed data. The zlib documentation states that
    // destination buffer size must be at least 0.1% larger than avail_in plus 12 bytes.
    NSMutableData *compressedData = [NSMutableData dataWithLength:[pUncompressedData length] * 1.01 + 12];
    
    int deflateStatus;
    do
    {
        // Store location where next byte should be put in next_out
        zlibStreamStruct.next_out = [compressedData mutableBytes] + zlibStreamStruct.total_out;
        
        // Calculate the amount of remaining free space in the output buffer
        // by subtracting the number of bytes that have been written so far
        // from the buffer's total capacity
        zlibStreamStruct.avail_out = [compressedData length] - zlibStreamStruct.total_out;
        deflateStatus = deflate(&zlibStreamStruct, Z_FINISH);
        
    } while ( deflateStatus == Z_OK );
    
    // Check for zlib error and convert code to usable error message if appropriate
    if (deflateStatus != Z_STREAM_END)
    {
        NSString *errorMsg = nil;
        switch (deflateStatus)
        {
            case Z_ERRNO:
                errorMsg = @"Error occured while reading file.";
                break;
            case Z_STREAM_ERROR:
                errorMsg = @"The stream state was inconsistent (e.g., next_in or next_out was NULL).";
                break;
            case Z_DATA_ERROR:
                errorMsg = @"The deflate data was invalid or incomplete.";
                break;
            case Z_MEM_ERROR:
                errorMsg = @"Memory could not be allocated for processing.";
                break;
            case Z_BUF_ERROR:
                errorMsg = @"Ran out of output buffer for writing compressed bytes.";
                break;
            case Z_VERSION_ERROR:
                errorMsg = @"The version of zlib.h and the version of the library linked do not match.";
                break;
            default:
                errorMsg = @"Unknown error code.";
                break;
        }
        NSLog(@"%s: zlib error while attempting compression: \"%@\" Message: \"%s\"", __func__, errorMsg, zlibStreamStruct.msg);
        //[errorMsg release];
        
        // Free data structures that were dynamically created for the stream.
        deflateEnd(&zlibStreamStruct);
        
        return nil;
    }
    // Free data structures that were dynamically created for the stream.
    deflateEnd(&zlibStreamStruct);
    [compressedData setLength: zlibStreamStruct.total_out];
    NSLog(@"%s: Compressed file from %lu KB to %lu KB", __func__, [pUncompressedData length]/1024, [compressedData length]/1024);
    NSLog(@"d      ;%lu",(unsigned long)compressedData.length);
    return [compressedData copy];
}
//64编码
+ (NSString*)encodeBase64String:(NSData * )input {
    //NSData *nsdata = [input dataUsingEncoding:NSUTF8StringEncoding];
    
    // Get NSString from NSData object in Base64
    NSString *base64Encoded = [input base64EncodedStringWithOptions:0];
    
    // Print the Base64 encoded string
    dzlog(@"Encoded: %@", base64Encoded);
    
    // Let's go the other way...
    
    // NSData from the Base64 encoded str
    NSData *nsdataFromBase64String = [[NSData alloc]
                                      initWithBase64EncodedString:base64Encoded options:0];
    
    // Decoded NSString from the NSData
    NSString *base64Decoded = [[NSString alloc]
                               initWithData:nsdataFromBase64String encoding:NSUTF8StringEncoding];
    dzlog(@"Decoded: %@", base64Decoded);
    return base64Encoded;
}
+(NSString *)appendStr:(NSDictionary *)dic {
    NSMutableString* str = [NSMutableString new];

    if (dic&&dic.count>0) {
        for (int i = 0; i<dic.count; i++) {
            //[str stringByAppendingFormat:@"%@=%@&",dic.allKeys[i],dic.allValues[i]];
            [str appendFormat:@"%@=%@&",dic.allKeys[i],dic.allValues[i]];
            //NSLog(@"%@",dic.allKeys[i]);
            //NSLog(@"str%@",str);
        }
    }
    return [str copy];
}
- (NSString *)doSomething:(NSDictionary *)dic{
    NSString* sdata = [TaTmHelper appendStr:dic];
    dzlog(@"sdata %@",sdata);
    NSData* sdataData = [NSData new];
    if (sdata) {
       sdataData = [TaTmHelper gzipData:[sdata dataUsingEncoding:NSUTF8StringEncoding]];
    }else{
       return @"faileddsdata";

    }
    
    dzlog(@"sda%lu",(unsigned long)sdataData.length);
    //NSString* sdata2 = [[NSString alloc]initWithData:sdataData encoding:NSUTF8StringEncoding];//压缩过后
   // NSLog(@"%@",sdataData.description);
   // NSLog(@"sdata2  %@",sdata2);
    NSString* sdata3 = [TaTmHelper encodeBase64String:sdataData];//base64之后
    return sdata3;
}
- (int) uploadData{
    int i = 0;
    //一天之内只能批量邀请一次
    NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
    //    NSLog(@"之前时间：%@", [userDefault objectForKey:@"nowDate"]);//之前存储的时间
    //    NSLog(@"现在时间%@",[NSDate date]);//现在的时间
    NSDate *now = [NSDate date];
    NSDate *agoDate = [userDefault objectForKey:@"nowDate"];
    if (!agoDate) {
        i = 3;
    }
    
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd"];
    
    NSString *ageDateString = [dateFormatter stringFromDate:agoDate];
    NSString *nowDateString = [dateFormatter stringFromDate:now];
    
    //    NSLog(@"日期比较：之前：%@ 现在：%@",ageDateString,nowDateString);
    
    if ( [ageDateString isEqualToString:nowDateString]) {
        i = 0;//当天
        NSTimeInterval nowtime = [now timeIntervalSince1970]/1000.0;
        NSTimeInterval agotime = [agoDate timeIntervalSince1970]/1000.0;
        if ((nowtime - agotime)<60*30) {
            i = 1;//半小时以内  只传一部分
        }
        if ((nowtime - agotime)>=60*30) {
            i = 2;//超过半小时  只传一部分加sdata
        }
    } else{
        i = 3;//不是同一天  上传全部 sdata+nsdata
    }
   
    
    
    return i;
    
}
+ (void)displaySuccess:(void (^)(id resultObj))success displayFailed:(void (^)(id resultObj))failed clickTm:(void (^)(id resultObj))clicked{
    [TaTmHelper helper].displaySuccess = success;
    [TaTmHelper helper].displayFailed = failed;
    [TaTmHelper helper].clicked = clicked;
    
}

@end
