//
//  PlayerViewController+backupsFile.m
//  隐私保护
//
//  Created by xd h on 2024/1/3.
//

#import "PlayerViewController+backupsFile.h"

@implementation PlayerViewController (backupsFile)
/*****************备份相关**********************************/
- (void)beginGotoBackupsFileFun:(NSNotification *)notification
{
    photosBackupsTaskModel *uploadFileDataMod = [notification object];
    //HLog(@"%@",uploadFileDataMod);
    
    
    self.curPhotosBackupsTaskMod = uploadFileDataMod;
    
    if(![uploadFileDataMod isKindOfClass:[photosBackupsTaskModel class]]){
        HLog(@"备份的文件类型不对");
        return;
    }
    
    [self ApplyBackupsFileFun];
}

#pragma mark 申请备份文件
- (void)ApplyBackupsFileFun
{
    //if(!self.taskUid){
        self.backupsTaskUid = [iTools getTaskUidStr];
        
        if([self.backupsTaskUid isEqualToString:self.downloadFileTaskUid]
           ||[self.backupsTaskUid isEqualToString:self.taskUid])
        {//重新生成taskUid
            [self ApplyBackupsFileFun];
            return;
        }
    
        self.backupsFileName = self.curPhotosBackupsTaskMod.filename;
        if(self.curPhotosBackupsTaskMod.curUploadFileType == uploadFileTypeVideo){
           
        }
        else{
            self.backupsAllFileData = self.curPhotosBackupsTaskMod.imageData;
        }
        
        self.backupsIndexOfUploadFlie = 0;
        
    //}
    
    NSString * backupsDefaultPath = [HWDataManager getStringWithKey:stringKeyAddSn(Const_photo_backups_default_path)];
    
    if(!backupsDefaultPath || backupsDefaultPath.length == 0){
        backupsDefaultPath = Const_default_backups_path;
        [HWDataManager setStringWithKey:stringKeyAddSn(Const_photo_backups_default_path) value:backupsDefaultPath];
    }
    
    NSString *lastStr= [backupsDefaultPath substringFromIndex:backupsDefaultPath.length-1];
    if(![lastStr isEqualToString:@"/"]){
        backupsDefaultPath = [[NSString alloc] initWithFormat:@"%@/",backupsDefaultPath];
    }
   
    NSString * commandStr = [RCCommandHelp applyForBackupsFileBy:self.backupsTaskUid withFileName:self.backupsFileName withSavePath:backupsDefaultPath];
    
    //NSString * commandStr = [RCCommandHelp applyForUploadFileBy:self.taskUid  filePath:self.fileName];
    
    [self.commandChannelManager rc_sendData:commandStr];
}

- (void)applyBackupsFileServiceResponseFun:(NSDictionary *)dataDict
{
    if([dataDict isKindOfClass:[NSDictionary class]]){
        if ([[dataDict allKeys] containsObject:@"data"]) {
            NSDictionary *data = dataDict[@"data"];

            if ([[data allKeys] containsObject:@"status"]) {
                NSString  *status = [data objectForKey:@"status"];
                if(![status isKindOfClass:[NSString class]]){
                    status = [[NSString  alloc] initWithFormat:@"%@",status];
                }
                
               if ([status isEqualToString:@"0"]){
                    if ([[data allKeys] containsObject:@"taskUid"]) {
                        NSString *taskUid = data[@"taskUid"];
                        if(![status isKindOfClass:[NSString class]]){
                            taskUid = [[NSString  alloc] initWithFormat:@"%@",taskUid];
                        }
                        
                        if(taskUid &&  [taskUid isEqualToString:self.backupsTaskUid]){
                            
                            NSNumber * fileLengthNum = @0;
                            if ([[data allKeys] containsObject:@"fileLength"])
                            {
                                fileLengthNum = data[@"fileLength"];
                            }
                            
                            
                            if(self.curPhotosBackupsTaskMod.curUploadFileType == uploadFileTypeImage){
                                
                                if([fileLengthNum integerValue] == self.curPhotosBackupsTaskMod.totalBytes){
                                    self.curPhotosBackupsTaskMod.didBackupsOneFileType = YES;
                                    HLog(@"文件已备份");
                                    [[backupsFileManager shareInstance] backupsFileDoneFun];
                                    
                                }
                                else{
                                    self.curPhotosBackupsTaskMod.didBackupsOneFileType = NO;
                                    [self beginGotoBackupsImageFun:fileLengthNum];
                                }
                                
                            }
                            else{
                                [self backupsBeginGotoUploadVidelFun:fileLengthNum];
                            }
                        }
                    }
                   
                }
                else if([status isEqualToString:@"3"])
                {
                    NSString *tipStr = NSLocalizedString(@"disk_not_find_tip",nil);
                    [[backupsFileManager shareInstance] changeBackupsFileStateToFailWith:tipStr];
                    mainBlock(^{
                        [[iToast makeText:tipStr] show];
                    });
                    
                }
                else if ([status isEqualToString:@"5"]) {
                    NSString *tipStr = NSLocalizedString(@"disk_space_not_tip",nil);
                    [[backupsFileManager shareInstance] changeBackupsFileStateToFailWith:tipStr];
                    mainBlock(^{
                        [[iToast makeText:tipStr] show];
                    });
                }
                else //if([status isEqualToString:@"1"])
                {
                    [[backupsFileManager shareInstance] getDataWrongToChangeFailFun];
                }
            }
        }
        else{
            //异常
            [self tryAgainApplyBackupsFun];
        }
    }
    else{
        //异常
        [self tryAgainApplyBackupsFun];
    }
}

#pragma mark 遇到异常时 重新上传
- (void)tryAgainApplyBackupsFun
{
    self.backupsTaskUid = nil;
    [self ApplyBackupsFileFun];
}

#pragma mark 图片上传
-(void)beginGotoBackupsImageFun:(NSNumber*)fileLengthNum{
    
    self.backupsCutFileDataArr = [self backupsFileCutPartsBy:self.backupsAllFileData withDidUpLoadSize:[fileLengthNum integerValue]];
    
    if(!self.backupsCutFileDataArr || self.backupsCutFileDataArr.count == 0){
        [[backupsFileManager shareInstance] getDataWrongToChangeFailFun];
        return;
    }
    
    //答复的taskUid 跟申请的一致 开发发送内容
    [self backupsFileFun];
}

#pragma mark 视频上传
//每次从文件重新切一片 传一片
-(void)backupsBeginGotoUploadVidelFun:(NSNumber*)fileLengthNum{
    
    NSData *data = [self backupsCutVideoFileFunAtIndex:fileLengthNum.longLongValue];
    HLog(@"data leng:%ld",[data length]);

    if([data length] == 0){
        [self clearBackupsFileDataFun];
        [[backupsFileManager shareInstance] getDataWrongToChangeFailFun];
        HLog(@"hxd fail 备份任务异常终止")
        return;
    }
    
    self.backupsAllFileData  = data;
    self.backupsCutFileDataArr  = [self backupsFileCutPartsBy:self.backupsAllFileData withDidUpLoadSize:0];
    self.backupsIndexOfUploadFlie  = 0;
    
    //return;

//    NSString*videoPathStr = [cachesFileManager getFilePathWithName:self.curUploadFileDataMod.filename type:uploadFileTypeVideo];
//    self.AllFileData = [NSData dataWithContentsOfFile:videoPathStr];

   // self.cutFileDataArr = [self fileCutPartsBy:self.AllFileData withDidUpLoadSize:[fileLengthNum integerValue]];
    
    if(!self.backupsCutFileDataArr || self.backupsCutFileDataArr.count == 0){
        [self clearBackupsFileDataFun];
        [[backupsFileManager shareInstance] getDataWrongToChangeFailFun];
        
        HLog(@"hxd fail 备份任务异常终止")
        return;
    }
    
    //答复的taskUid 跟申请的一致 开发发送内容
    [self backupsFileFun];
}

#pragma mark 分段读视频文件
-(NSData*)backupsCutVideoFileFunAtIndex:(NSUInteger)dataIndex{
    NSString *filePath = [cachesFileManager getFilePathWithName:self.curPhotosBackupsTaskMod.filename type:uploadFileTypeVideo]; // 文件路径
    
    NSFileManager *manager0 = [NSFileManager defaultManager];
    if(![manager0 fileExistsAtPath:filePath]) {
     
        return [NSData new];
    }
    
    NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:filePath]; // 创建文件句柄
      
    // 设置分段读取的大小，这里以每次读取1KB为例
    //const NSUInteger chunkSize = 50 * 1024 *1024;
    const NSUInteger chunkSize = 5 * 1024 *1024;
    NSMutableData *data = [NSMutableData data];
    
    if (fileHandle) {
       
        long long endOfFile = [fileHandle seekToEndOfFile];
        
        if(dataIndex == 0 || self.curPhotosBackupsTaskMod.totalBytes == 0){
            self.curPhotosBackupsTaskMod.totalBytes = endOfFile;
        }
        
        if (endOfFile >=  chunkSize) {
            
            // 读取文件的分段数据到某个位置
            [fileHandle seekToFileOffset:dataIndex];
            
            // 读取文件的分段数据
            NSData* chunk = [fileHandle readDataOfLength:chunkSize];
            if (chunk) {
                [data appendData:chunk];
            }
        }
        else{
            // 读取文件的分段数据到某个位置
            [fileHandle seekToFileOffset:dataIndex];
            
            [data appendData:[fileHandle readDataToEndOfFile]];
        }
        
        // 在这里可以对文件内容进行处理
        // ...
        
        // 关闭文件句柄
        [fileHandle closeFile];
    }
    
    return data;
}


- (void)backupsFileFunServiceResponseFun:(NSDictionary *)dataDict
{
    //"type":"backUpFileRandomRet","data":{"progress":"0\/1","filePath":"/sdcard/DCIM/IMG_0889.JPG","fileLenth":258066,"status":"0","msg":"success"}}
    
    if([dataDict isKindOfClass:[NSDictionary class]]){
        if ([[dataDict allKeys] containsObject:@"data"]) {
            NSDictionary *data = dataDict[@"data"];

            if ([[data allKeys] containsObject:@"status"]) {
                NSString  *status = [data objectForKey:@"status"];
                if(![status isKindOfClass:[NSString class]]){
                    status = [[NSString  alloc] initWithFormat:@"%@",status];
                }
                
                if ([status isEqualToString:@"1"]) {
                    [[backupsFileManager shareInstance] getDataWrongToChangeFailFun];
                    
                }else if ([status isEqualToString:@"2"]){
                    NSString *tipStr = NSLocalizedString(@"disk_not_find_tip",nil);
                    [[backupsFileManager shareInstance] changeBackupsFileStateToFailWith:tipStr];
                    mainBlock(^{
                        [[iToast makeText:tipStr] show];
                    });
                }
                else if ([status isEqualToString:@"5"]){
                    NSString *tipStr = NSLocalizedString(@"disk_space_not_tip",nil);
                    [[backupsFileManager shareInstance] changeBackupsFileStateToFailWith:tipStr];
                    mainBlock(^{
                        [[iToast makeText:tipStr] show];
                    });
                }
                else if ([status isEqualToString:@"0"]){
                    
                    NSNumber * fileLengthNum = @0;
                    if ([[data allKeys] containsObject:@"fileLenth"])
                    {
                        fileLengthNum = data[@"fileLenth"];
                    }
                    
                    [self handleBackupsingFun:fileLengthNum];
                }
            }
        }
        else{
            //异常
            [self tryAgainApplyBackupsFun];
        }
    }
    else{
        //异常
        [self tryAgainApplyBackupsFun];
    }
    
}

#pragma mark 处理上传过程
- (void)handleBackupsingFun:(NSNumber*)fileLengthNum
{
    BOOL isCanUseCellular = [HWDataManager getBoolWithKey:stringKeyAddSn(Const_file_backups_canUse_Cellular)];

    if(!isCanUseCellular){//不允许流量备份
        //
        if([AFNetworkReachabilityManager sharedManager].networkReachabilityStatus == AFNetworkReachabilityStatusReachableViaWWAN){
            self.curPhotosBackupsTaskMod.isBackupsSuspendType = backupsSuspendByOther;
            self.curPhotosBackupsTaskMod.curBackupsState = backupsStateSuspend;
            [[backupsFileManager shareInstance] changeBackupsFileStateFun];
        }

    }
    
    
    if(self.curPhotosBackupsTaskMod.isBackupsSuspendType != backupsSuspendNone){
        [self clearBackupsFileDataFun];
        return;
    }
    
    [[backupsFileManager shareInstance] changeBackupsFileStateFun];
    
    if(self.backupsIndexOfUploadFlie < self.backupsCutFileDataArr.count -1) {
        
        self.backupsIndexOfUploadFlie ++;
        [self backupsFileFun];
    }
    else if(self.curPhotosBackupsTaskMod.curUploadFileType == uploadFileTypeVideo && fileLengthNum && fileLengthNum.longLongValue < self.curPhotosBackupsTaskMod.totalBytes){
        //视频做了二次切割 不一定上传完了
        HLog(@"视频上传传完一片 再来一片");
        [self backupsBeginGotoUploadVidelFun:fileLengthNum];
    }
    else{
        HLog(@"备份完成");
        
        [[backupsFileManager shareInstance] backupsFileDoneFun];
    }
}

-(void)clearBackupsFileDataFun{
    //上传数据清空
    self.backupsTaskUid = nil;
    self.backupsFileName = nil;
    self.backupsAllFileData = nil;
    self.backupsIndexOfUploadFlie = 0;
    self.backupsCutFileDataArr = nil;
    self.curPhotosBackupsTaskMod = nil;
    
}

- (Byte)getBCC:(NSData *)data {
    Byte bcc = 0;
    unsigned char *bytes = (unsigned char *)[data bytes];
    for (int i = 0; i < [data length]; i++) {
        bcc = (Byte)(bcc ^ bytes[i]);
    }
    return bcc;
}

#pragma mark 文件切片
-(NSMutableArray *)backupsFileCutPartsBy:(NSData*)curData withDidUpLoadSize:(NSInteger)didLoadSize{
 
    NSData * data = curData;
    
    NSUInteger allLength = data.length;
    
    NSUInteger subs = EachPieceSzie;//1*1024*1024;//4096;//要切片的大小，我这里设置的是4096字节
    //NSUInteger subs = 31*1024;//4096;//要切片的大小，内存没有暴增
    
    self.cutFileEachPieceSzie = subs;
    
    NSInteger index = 0;//起始位置
    
    if(didLoadSize != 0){
        if (didLoadSize % subs != 0){
            //出错了
            return nil;
        }
        else{
//            index = didLoadSize/subs;
//            allLength = allLength - didLoadSize;
            
            self.backupsIndexOfUploadFlie = didLoadSize/subs;
        }
    }

    NSMutableArray *dataArray =[NSMutableArray new];
    
    do {
        //@autoreleasepool {
            if (allLength>subs) {
                
                NSRange range =NSMakeRange(index*subs, subs);
                
                index++;
                
                //NSLog(@"%@",NSStringFromRange(range));
                
                [dataArray addObject:[data subdataWithRange:range]];
                
                allLength = allLength - subs;
                
            }else{
                NSRange range = NSMakeRange(index*subs, allLength);
                
                //NSLog(@"%@",NSStringFromRange(range));
                
                [dataArray addObject:[data subdataWithRange:range]];
                
                allLength = 0;
            }
        //}
        
    } while (allLength>0);
    
    HLog(@"dataArray leng:%ld",dataArray.count);//最后得到切片的结果，数组里面是NSData对象

    return dataArray;
}

// int转NSData
- (NSData *)int2Data:(int)i{
    Byte b0 = i & 0xff;
    Byte b1 = i >> 8 & 0xff;
    Byte b2 = i >> 16 & 0xff;
    Byte b3 = i >> 24 & 0xff;
    // 有大小端模式问题？
    //Byte result[] = {b0, b1, b2, b3};
    Byte result[] = {b3, b2, b1, b0};
    return [NSData dataWithBytes:result length:sizeof(result)];
}

// short转NSData
- (NSData *)short2Data:(short)i{
    Byte b0 = i & 0xff;
    Byte b1 = i >> 8 & 0xff;
    // 有大小端模式问题？
    //Byte result[] = {b0, b1, b2, b3};
    Byte result[] = { b1, b0};
    return [NSData dataWithBytes:result length:sizeof(result)];
}

#pragma mark 可以发送文件了
/*
文件数据字节流byte[]
  格式1:下载日志文件压缩包
       |head|msgType|taskId|    datalen            | curNum | totalNum|   data   |bcc校验|end|
  长度：  1      1      6 （curNum+totalNum+data）        4         4      datalen- 8   1     1
       0x68  0x0e                                                        0x16
    bcc校验从第1位 也就是从msgType起 到 校验位前（不包含校验位）数据作bcc校验
 */
- (void)backupsFileFun
{
    //HLog(@"上传文件%ld/%ld",self.indexOfUploadFlie +1,self.cutFileDataArr.count);
    
    if(self.backupsCutFileDataArr.count <= self.backupsIndexOfUploadFlie)
    {
        return;
    }
    
    //data
    NSData *curData = self.backupsCutFileDataArr[self.backupsIndexOfUploadFlie];
    //HLog(@"headData:%@",curData);
    
    //head
    unsigned char headNum = 104;
    NSData *headData = [NSMutableData dataWithBytes:&headNum length:sizeof(headNum)];
    //HLog(@"headData:%@",headData);
    
    //msgType
    //unsigned char msgType = 12;
    //unsigned char msgType = 15;
    unsigned char msgType = 16;
    NSData *msgTypeData = [NSMutableData dataWithBytes:&msgType length:sizeof(msgType)];
    //HLog(@"msgTypeData:%@",msgTypeData);
    
    //taskId
    NSData *taskIdData = [self.backupsTaskUid dataUsingEncoding:NSUTF8StringEncoding];
    //HLog(@"taskIdData:%@",taskIdData);
    
    //datalen
    //int datalenNum = int([curData length] +(4+4));
    int datalenNum = [curData length] + (4+4);
    //NSData *datalenData = [NSData dataWithBytes:&datalenNum length:sizeof(datalenNum)];
    NSData *datalenData = [self int2Data:datalenNum];
    //HLog(@"datalenData %@",datalenData);
    
    
    //curNum
    int curNum = (int)self.backupsIndexOfUploadFlie;
    //NSData *curNumData = [NSData dataWithBytes:&curNum length:sizeof(curNum)];
    NSData * curNumData = [self int2Data:curNum];
    //HLog(@"curNumData:%@",curNumData);
    
    //totalNum
    int totalNum = (int)self.backupsCutFileDataArr.count;
    //NSData *totalNumData = [NSData dataWithBytes:&totalNum length:sizeof(totalNum)];
    NSData * totalNumData = [self int2Data:totalNum];
    //HLog(@"totalNumData:%@",totalNumData);
    

    NSMutableData *checkBCCData = [NSMutableData new];
    [checkBCCData appendData:msgTypeData];
    [checkBCCData appendData:taskIdData];
    [checkBCCData appendData:datalenData];
    [checkBCCData appendData:curNumData];
    [checkBCCData appendData:totalNumData];
    [checkBCCData appendData:curData];
    
    long length = [curData length];
    //HLog(@"curData length %d",length);
    
    Byte bccCheck = [self getBCC:checkBCCData];
    //HLog(@"bcc 000 %d",bccCheck);
    
    //bcc校验
    char bccNum = (char)bccCheck;
    NSData *bccData = [NSMutableData dataWithBytes:&bccNum length:sizeof(bccNum)];
    //HLog(@"%@",bccData);
    
    //end
    unsigned char endNum = 22;
    NSData *endData = [NSMutableData dataWithBytes:&endNum length:sizeof(endNum)];
    //HLog(@"%@",endData);
    
    NSMutableData *sendData = [NSMutableData new];
    [sendData appendData:headData];
    [sendData appendData:checkBCCData];
    [sendData appendData:bccData];
    [sendData appendData:endData];
    
    //HLog(@"sendData length %ld",[sendData length]);
    [self.commandChannelManager rc_sendData:sendData];
    //HLog(@"文件上传sendData %@",sendData);
}



@end
