//
//  FileUtils.m
//  zhuxin
//
//  Created by 豆豆 on 14/11/24.
//  Copyright (c) 2014年 ding wei. All rights reserved.
//

#import "FileUtils.h"
#import <CommonCrypto/CommonDigest.h>  
#import "NSDate+Common.h"
#import "NSDate+Helper.h"
#import "Utils.h"
#define FileHashDefaultChunkSizeForReadingData 1024*8
@interface FileUtils()<UIDocumentInteractionControllerDelegate>
@property(nonatomic,retain)UIDocumentInteractionController *documentInteractionController;
@property (nonatomic , weak)UIViewController *fileShowController;
@end
static FileUtils *fileUtils;
@implementation FileUtils

+ (long long) fileSizeAtPath:(NSString*) filePath{
    NSFileManager* manager = [NSFileManager defaultManager];
    if ([manager fileExistsAtPath:filePath]){
        return [[manager attributesOfItemAtPath:filePath error:nil] fileSize];
    }
    return 0;
}

//用户文件保存目录
+(NSString *)userFileDir
{
    NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentPath=[paths objectAtIndex:0];
    documentPath = [documentPath stringByAppendingPathComponent:@"/user_file"];
    NSFileManager* manager = [NSFileManager defaultManager];
    BOOL isd;
    BOOL isEx = [manager fileExistsAtPath:documentPath isDirectory:&isd];
    if (!isEx) {
        [manager createDirectoryAtPath:documentPath withIntermediateDirectories:NO attributes:Nil error:nil];
    }
    return documentPath;
}


//返回一个路径
+(NSString *)userFileDirTemp
{
    NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentPath=[paths objectAtIndex:0];
    documentPath = [documentPath stringByAppendingPathComponent:@"/user_file_temp"];
    NSFileManager* manager = [NSFileManager defaultManager];
    BOOL isd;
    BOOL isEx = [manager fileExistsAtPath:documentPath isDirectory:&isd];
    if (!isEx) {
        [manager createDirectoryAtPath:documentPath withIntermediateDirectories:NO attributes:Nil error:nil];
    }
    return documentPath;
}

//获取声音文件的路径 并返回它的完整路径
+ (NSString *)voiceFilePath:(NSString*)fileName {
    //获取Documents目录的路径
//    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//    NSString *documentsDirectory = [paths objectAtIndex:0];
    //拼接 voice  成为一个完整的路径
    /*
     stringByAppendingPathComponent: 是在 路径<documentsDictionary>后面添加 '/' 连接 <voice>
     stringByAppendingString: 是在 documentsDictionary 后面添加后缀的意思
     */
//    NSString *voiceDirectory = [documentsDirectory stringByAppendingPathComponent:@"voice"];
    //fileExissAtPath: 判断路径是否存在
    if ( ! [[NSFileManager defaultManager] fileExistsAtPath:VoiceFolderFullRouter]) {
        //如果不存在 就创建路径
        [[NSFileManager defaultManager] createDirectoryAtPath:VoiceFolderFullRouter withIntermediateDirectories:YES attributes:nil error:NULL];
    }
    return [VoiceFolderFullRouter stringByAppendingPathComponent:fileName];
}


+(NSString *)getFileNameFromDownloadUrl:(NSString*) url
{
    NSString *fileName = [url lastPathComponent];
    NSArray *strarray = [fileName componentsSeparatedByString:@"?"];
    fileName = strarray[1];
    return fileName;

}

//从获取MD5
+(NSString *)getMd5FromDownloadUrl:(NSString*) url{
    NSString *md5 = [url lastPathComponent];
    NSArray *strarray = [md5 componentsSeparatedByString:@"?"];
    md5 = strarray[0];
    md5 = [md5 stringByDeletingPathExtension];
    return md5;
}

//根据nsdata获取md5值
+ (NSString*)getMD5WithData:(NSData *)data
{
    const char* original_str = (const char *)[data bytes];
    unsigned char digist[CC_MD5_DIGEST_LENGTH]; //CC_MD5_DIGEST_LENGTH = 16
    CC_MD5(original_str, strlen(original_str), digist);
    NSMutableString* outPutStr = [NSMutableString stringWithCapacity:10];
    for(int  i =0; i<CC_MD5_DIGEST_LENGTH;i++){
        [outPutStr appendFormat:@"%02x",digist[i]];//小写x表示输出的是小写MD5，大写X表示输出的是大写MD5
    }
    
    return [outPutStr lowercaseString];
    
}

+ (NSString *)getFileExtWithFileName:(NSString *)fileName
{
    NSString *ext = [fileName componentsSeparatedByString:@"."].lastObject;
    return ext;
}


+(NSString*)getFileMD5WithPath:(NSString*)path

{
    return (__bridge_transfer NSString *)FileMD5HashCreateWithPath((__bridge CFStringRef)path, FileHashDefaultChunkSizeForReadingData);
}

+(FileModel *)getFileModelWithPath:(NSString*)path
{
//    path = [NSString stringWithFormat:@"%@/%@",FileFolderFullRouter,path];
    NSFileManager *fileMgr = [NSFileManager defaultManager];
    if([fileMgr fileExistsAtPath:[NSString stringWithFormat:@"%@/%@",FileFolderFullRouter,path]])
    {
        FileModel *fileModel = [FileModel new];
        fileModel.birefFileType = BriefFileTypeOther;
        fileModel.fileSize = [NSString stringWithFormat:@"%lld",[[fileMgr attributesOfItemAtPath:[NSString stringWithFormat:@"%@/%@",FileFolderFullRouter,path] error:nil]fileSize]];
        fileModel.fileName = path.lastPathComponent;
        fileModel.fileLocalPath = path;
        fileModel.fileCreateTime = [[fileMgr attributesOfItemAtPath:[NSString stringWithFormat:@"%@/%@",FileFolderFullRouter,path] error:nil]fileCreationDate];
        fileModel.md5 = [self getFileMD5WithPath:fileModel.fileFullLocalPath];
        
        return fileModel;
        
    }else return nil;
}

+(FileModel *)getPicFileModelWithPath:(NSString*)path;//从本地文件获取图片文件属性,大小单位byte
{
    NSFileManager *fileMgr = [NSFileManager defaultManager];
    if([fileMgr fileExistsAtPath:[NSString stringWithFormat:@"%@/%@",PhotosMessageDir,path]])
    {
        FileModel *fileModel = [FileModel new];
        fileModel.birefFileType = BriefFileTypePic;
        fileModel.fileSize = [NSString stringWithFormat:@"%lld",[[fileMgr attributesOfItemAtPath:[NSString stringWithFormat:@"%@/%@",PhotosMessageDir,path] error:nil]fileSize]];
       
        fileModel.fileLocalPath = path;
        fileModel.fileCreateTime = [[fileMgr attributesOfItemAtPath:[NSString stringWithFormat:@"%@/%@",PhotosMessageDir,path] error:nil]fileCreationDate];
        fileModel.fileName = [NSString stringWithFormat:@"%@",[fileModel.fileCreateTime stringWithFormat:@"yyyy-MM-dd hh:mm:ss"]];
        fileModel.md5 = [self getFileMD5WithPath:fileModel.fileFullLocalPath];
        return fileModel;
        
    }else return nil;

}


//    ******           这里不懂          ******     //


CFStringRef FileMD5HashCreateWithPath(CFStringRef filePath,size_t chunkSizeForReadingData) {
    
    // Declare needed variables
    
    CFStringRef result = NULL;
    
    CFReadStreamRef readStream = NULL;
    
    // Get the file URL
    
    CFURLRef fileURL =
    
    CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
                                  
                                  (CFStringRef)filePath,
                                  
                                  kCFURLPOSIXPathStyle,
                                  
                                  (Boolean)false);
    
    if (!fileURL) goto done;
    
    // Create and open the read stream
    
    readStream = CFReadStreamCreateWithFile(kCFAllocatorDefault,
                                            
                                            (CFURLRef)fileURL);
    
    if (!readStream) goto done;
    
    bool didSucceed = (bool)CFReadStreamOpen(readStream);
    
    if (!didSucceed) goto done;
    
    // Initialize the hash object
    
    CC_MD5_CTX hashObject;
    
    CC_MD5_Init(&hashObject);
    
    // Make sure chunkSizeForReadingData is valid
    
    if (!chunkSizeForReadingData) {
        
        chunkSizeForReadingData = FileHashDefaultChunkSizeForReadingData;
        
    }
    
    // Feed the data to the hash object
    
    bool hasMoreData = true;
    
    while (hasMoreData) {
        
        uint8_t buffer[chunkSizeForReadingData];
        
        CFIndex readBytesCount = CFReadStreamRead(readStream,(UInt8 *)buffer,(CFIndex)sizeof(buffer));
        
        if (readBytesCount == -1) break;
        
        if (readBytesCount == 0) {
            
            hasMoreData = false;
            
            continue;
            
        }
        
        CC_MD5_Update(&hashObject,(const void *)buffer,(CC_LONG)readBytesCount);
        
    }
    
    // Check if the read operation succeeded
    
    didSucceed = !hasMoreData;
    
    // Compute the hash digest
    
    unsigned char digest[CC_MD5_DIGEST_LENGTH];
    
    CC_MD5_Final(digest, &hashObject);
    
    // Abort if the read operation failed
    
    if (!didSucceed) goto done;
    
    // Compute the string result
    
    char hash[2 * sizeof(digest) + 1];
    
    for (size_t i = 0; i < sizeof(digest); ++i) {
        
        snprintf(hash + (2 * i), 3, "%02x", (int)(digest[i]));
        
    }
    
    result = CFStringCreateWithCString(kCFAllocatorDefault,(const char *)hash,kCFStringEncodingUTF8);
    
    
    
done:
    
    if (readStream) {
        
        CFReadStreamClose(readStream);
        
        CFRelease(readStream);
        
    }
    
    if (fileURL) {
        
        CFRelease(fileURL);
        
    }
    
    return result;
    
}

+ (FileUtils *)shareFileUtils
{
  
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        fileUtils = [[FileUtils alloc]init];
    });
    return fileUtils;
}
//文件预览
- (void)filePreViewWithOrigionPath:(NSString *)path showController:(UIViewController *)viewController
{
    self.fileShowController = viewController;
    //原始path
    if ([[path.lastPathComponent componentsSeparatedByString:@"."].lastObject isEqualToString:@"txt"]||[[path.lastPathComponent componentsSeparatedByString:@"."].lastObject isEqualToString:@"TXT"]) {
        //[URLSTR stringByReplacingOccurrencesOfString:@"file://" withString:@""]
        
        [self transformEncodingWithFilePath:path];
        
        
    }
    
    path = [[NSString stringWithFormat:@"file://%@",path]stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    
    self.documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL URLWithString:path]];
    self.documentInteractionController.delegate = self;//设置代理
    
    [Utils showWaitingToView:self.fileShowController.view];
    
    __block BOOL canpreview;
    __weak typeof(self.fileShowController.view)weakView = self.fileShowController.view;
    __weak typeof(self)weakself = self;
    dispatch_async(dispatch_get_main_queue(), ^{
        
        canpreview = [weakself.documentInteractionController presentPreviewAnimated:NO];
        
        [Utils HiddenWaitingToView:weakView];
        
        
        if (canpreview){
            //可预览的格式
            
            weakself.documentInteractionController.name = [path.lastPathComponent stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        }
        else{
            
            [weakself.documentInteractionController presentOptionsMenuFromBarButtonItem:weakself.fileShowController.navigationItem.rightBarButtonItem animated:YES];
        }
    });
    

    
}

+ (void)authClearFiles
{
//    
//    GeneralSetting *generalSetting = [GeneralSetting returnGeneralSetting];
//    
//    if (generalSetting.isNeedClearFileOnTime.integerValue) {
//    
//        NSError *error = nil;
//        
//        NSArray *fileContents = [[NSFileManager defaultManager]contentsOfDirectoryAtPath:FileFolderFullRouter error:&error];
//        
//        NSArray *photoContents = [[NSFileManager defaultManager]contentsOfDirectoryAtPath:PhotosMessageDir error:&error];
//        
//        for (NSString *fileContent in fileContents) {
//            
//           NSDate *contentDate = [[[NSFileManager defaultManager] attributesOfItemAtPath:[NSString stringWithFormat:@"%@/%@",FileFolderFullRouter,fileContent] error:&error]fileCreationDate];
//            
//            NSTimeInterval expirTime = [[NSDate date] timeIntervalSinceDate:contentDate];
//            
//            if (expirTime >= generalSetting.clearFileTimeCycle.integerValue * 24 * 3600){
//            
//                [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@/%@",FileFolderFullRouter,fileContent] error:&error];
//                
//            }
//        }
//        
//        
//        for (NSString *photoContent in photoContents) {
//            
//             NSDate *contentDate = [[[NSFileManager defaultManager] attributesOfItemAtPath:[NSString stringWithFormat:@"%@/%@",PhotosMessageDir,photoContent] error:&error]fileCreationDate];
//            
//            NSTimeInterval expirTime = [[NSDate date] timeIntervalSinceDate:contentDate];
//            
//            if (expirTime >= generalSetting.clearFileTimeCycle.integerValue * 24 * 3600){
//                
//                [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@/%@",PhotosMessageDir,photoContent] error:&error];
//                
//            }
//        }
//        
//    
//    }
}

#pragma MARK --
#pragma MARK -- doucumentControllerDleegate
-(UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller{
    return self.fileShowController;
}


- (void)transformEncodingWithFilePath:(NSString *)filePath
{     //调用上述转码方法获取正常字符串
    NSString *body = [self examineTheFilePathStr:filePath];     //转换为二进制
    if (body) {
        NSData *data = [body dataUsingEncoding:NSUTF16StringEncoding];     //覆盖原来的文件
        [data writeToFile:filePath atomically:YES];
    }
    //此时在读取该文件，就是正常格式啦
}

- (NSString *)examineTheFilePathStr:(NSString *)str
{
    NSStringEncoding *useEncodeing = nil;
    //带编码头的如utf-8等，这里会识别出来
    NSString *body = [NSString stringWithContentsOfFile:str usedEncoding:useEncodeing error:nil];//识别不到，按GBK编码再解码一次.这里不能先按GB18030解码，否则会出现整个文档无换行bug
    if (!body) {
        body = [NSString stringWithContentsOfFile:str encoding:0x80000632 error:nil];
    }
    //还是识别不到，按GB18030编码再解码一次.
    if (!body) {
        body = [NSString stringWithContentsOfFile:str encoding:0x80000631 error:nil];
    }
    return body;//有值代表需要转换  为空表示不需要转换
    
    
    
}



@end
