//
//  CloudDownloadSession.m
//  zhuxun
//
//  Created by winsoft on 17/6/29.
//
//

#import "CloudDownloadSession.h"
#import "HttpRequest.h"
#import "CloudStorageDB.h"

#define MaxTryTimes 3
@interface CloudDownloadSession()

@property (nonatomic , strong) NSMutableDictionary *successBlocksDict;
@property (nonatomic , strong) NSMutableDictionary *failureBlocksDict;
@property (nonatomic , strong) NSMutableDictionary *progressBlocksDict;
@property (nonatomic , strong) WSDownloadSession *downloadSession;
@property (nonatomic , copy) NSDate *lastRecordTime;
/**
 *  失败重试次数
 */
@property (nonatomic , assign) NSInteger failedAndTryTimes;

@end
@implementation CloudDownloadSession

- (NSMutableDictionary *)successBlocksDict
{
    if (!_successBlocksDict) {
        _successBlocksDict = [NSMutableDictionary dictionary];
    }
    
    return _successBlocksDict;
}

- (NSMutableDictionary *)failureBlocksDict
{
    if (!_failureBlocksDict) {
        _failureBlocksDict = [NSMutableDictionary dictionary];
    }
    
    return _failureBlocksDict;
}

- (NSMutableDictionary *)progressBlocksDict
{
    if (!_progressBlocksDict) {
        _progressBlocksDict = [NSMutableDictionary dictionary];
    }
    
    return _progressBlocksDict;
}

+ (CloudDownloadSession *)startDownloadFileWithFileDownUpModel:(CSFileDownUpModel *)fileDownUpModel
{
    CloudDownloadSession *downLoadSession = [[CloudDownloadSession alloc]initDowunLoadFileWithFileDownUpModel:fileDownUpModel];
    
    return downLoadSession;
}

- (instancetype)initDowunLoadFileWithFileDownUpModel:(CSFileDownUpModel *)fileDownUpModel
{
    if (self = [super init]) {
        
        _fileDownUpModel = fileDownUpModel;
        
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self startDownloadFileWithfileDownUpModel:fileDownUpModel];
        });
        
        
        
    }
    
    return self;
}

- (void)startDownloadFileWithfileDownUpModel:(CSFileDownUpModel *)fileDownUpModel
{
    //     __weak typeof(self)weakSelf = self;
    
    //    return;
    
    [[HttpRequest sharedManager]cloudStorageGetFileDownloadURLWithMD5:fileDownUpModel.md5 complete:^(BOOL success, id data, NSError *error) {
        
        
        if (success && data) {
            
            NSString *url = data[@"url"];
            
            
            self.downloadSession = [WSDownloadSession oneDownloadSessionWithFileUrlString:url savePath:CloudStorageFullRouter localPath:fileDownUpModel.localRootPath fileMd5:fileDownUpModel.md5 UUID:fileDownUpModel.downUpUUID fileName:fileDownUpModel.name downloadedSize:fileDownUpModel.downUpSize fileSize:fileDownUpModel.size progressblock:nil
                                                                             successblock:nil failedBlock:nil];
            
            __weak typeof(self)weakSelf = self;
            
            self.downloadSession.downloadFailedBlock = ^(NSString* errMessage,NSString *msgUUID){
                
                if (weakSelf.failedAndTryTimes < MaxTryTimes) {
                    [weakSelf startDownloadFileWithfileDownUpModel:weakSelf.fileDownUpModel];
                    weakSelf.failedAndTryTimes ++;
                }else{
                    
                    weakSelf.fileDownUpModel.downUpStatus = DownUpStatusFailure;
                    
                    //存储
                    [kCloudStorageDB updateCSDownUpFileStatusWithCSFileDownUpModel:weakSelf.fileDownUpModel];
                    
                    int i = 0;
                    for (DownloadFailedUIBlock fileBlock in weakSelf.failureBlocksDict.allValues) {
                        
                        NSString *key = weakSelf.failureBlocksDict.allKeys[i];
                        if (fileBlock) {
                            //一方面,所有的model都注册了,另一方面,有时候多个model公共一个task.
                            fileBlock(errMessage,weakSelf.fileDownUpModel,key);
                        }
                        i++;
                    }
                    
                    if (weakSelf.downloadFailedDBBlock) {
                        weakSelf.downloadFailedDBBlock(errMessage,weakSelf.fileDownUpModel,weakSelf.fileDownUpModel.downUpUUID);
                    }
                }
                
                
            };
            
            self.downloadSession.downloadProgressBlock = ^(NSInteger receivedSize, NSInteger expectedSize, CGFloat progress,NSString *router,NSString *msgUUID){
                
                weakSelf.failedAndTryTimes = 0;
                
                weakSelf.fileDownUpModel.downUpSize = receivedSize;
                
                
                NSDate *now = [NSDate date];
                
                
                if (!weakSelf.lastRecordTime || [now timeIntervalSinceDate:weakSelf.lastRecordTime] >= 1) {
                    
                    //存储
                    [kCloudStorageDB updateCSDownUpFileStatusWithCSFileDownUpModel:weakSelf.fileDownUpModel];
                    
                    weakSelf.lastRecordTime = now;
                    
                    
                }
                
                int i = 0;
                for (DownloadProgressUIBlock downloadProgressBlock in weakSelf.progressBlocksDict.allValues){
                    
                    NSString *key = weakSelf.progressBlocksDict.allKeys[i];
                    //可将key传出.
                    if (downloadProgressBlock) {
                        downloadProgressBlock(receivedSize,expectedSize,progress,router,weakSelf.fileDownUpModel,key);
                    }
                    i++;
                }
                
                if(weakSelf.downloadProgressDBBlock)
                {
                    weakSelf.downloadProgressDBBlock(receivedSize,expectedSize,progress,router,weakSelf.fileDownUpModel,weakSelf.fileDownUpModel.downUpUUID);
                }
                
                
                
            };
            
            self.downloadSession.downloadSuccessBlock = ^(NSInteger receivedSize, NSString *localFullFileRouter,NSString *msgUUID){
                
                weakSelf.failedAndTryTimes = 0;
                
                weakSelf.fileDownUpModel.downUpSize = receivedSize;
                weakSelf.fileDownUpModel.downUpStatus = DownUpStatusSuccess;
                weakSelf.fileDownUpModel.localRootPath = localFullFileRouter;
                
                //存储
                [kCloudStorageDB updateCSDownUpFileStatusWithCSFileDownUpModel:weakSelf.fileDownUpModel];
                
                
                int i = 0;
                for (DownloadSuccessUIBlock succBlock in weakSelf.successBlocksDict.allValues) {
                    
                    NSString *key = weakSelf.successBlocksDict.allKeys[i];
                    if (succBlock) {
                        succBlock(receivedSize,localFullFileRouter,weakSelf.fileDownUpModel,key);
                    }
                    
                    i++;
                }
                
                //隔一秒?,否则上层通知完成和下层通知新的开始cell冲突 crash.
                
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    if (weakSelf.downloadSuccessDBBlock) {
                        weakSelf.downloadSuccessDBBlock(receivedSize,localFullFileRouter,weakSelf.fileDownUpModel,weakSelf.fileDownUpModel.downUpUUID);
                    }
                });
                
                
                [weakSelf.successBlocksDict removeAllObjects];
                [weakSelf.failureBlocksDict removeAllObjects];
                [weakSelf.progressBlocksDict removeAllObjects];
                
                weakSelf.successBlocksDict = nil;
                weakSelf.failureBlocksDict = nil;
                weakSelf.progressBlocksDict = nil;
            };
            
            
        }
        
        
        
        
    }];
    
}

- (void)giveBlockToUIWithUUID:(NSString *)uuid withProcessBlock:(DownloadProgressUIBlock)processBlock successBlock:(DownloadSuccessUIBlock)successBlock failBlock:(DownloadFailedUIBlock)failBlock;
{
    [self.successBlocksDict setObject:successBlock forKey:uuid];
    [self.progressBlocksDict setObject:processBlock forKey:uuid];
    [self.failureBlocksDict setObject:failBlock forKey:uuid];
    
}



- (void)cancerDownLoad
{
    [self.downloadSession cancer];
    
    _fileDownUpModel = nil;
    
    [self.successBlocksDict removeAllObjects];
    [self.failureBlocksDict removeAllObjects];
    [self.progressBlocksDict removeAllObjects];
    
    self.successBlocksDict = nil;
    self.failureBlocksDict = nil;
    self.progressBlocksDict = nil;
    
    self.downloadSuccessDBBlock = nil;
    self.downloadFailedDBBlock = nil;
    self.downloadProgressDBBlock = nil;
#warning 2017-07-18,待cell 新增pause block和start block. ->giveBlockToUIWithUUID
    //待通知所有注册的ui block上层暂停.(反之恢复的话也需要.)
}
@end
