//
//  DocumentViewer.m
//

#import "DocumentViewer.h"
#import "FileURLHelper.h"
#import <CommonCrypto/CommonDigest.h>
#ifdef IS_APPDOO_PREVIEW
#import "Prototype.h"
#import "ProjectResourcesCache.h"
#endif

@implementation NSString (SHA)

- (NSString *)sha1
{
	NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
	uint8_t digest[CC_SHA1_DIGEST_LENGTH];
	
	CC_SHA1(data.bytes, (CC_LONG)(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]];
	}
	
	return output;
}
@end

@implementation DocumentViewer {
	NSArray * _documentURLStrings;
	NSMutableDictionary * _requestsByURLString;
	NSMutableDictionary * _pathsByIndex;
}

- (void)awakeFromNib {
	[super awakeFromNib];
	// try again if the previous initialization failed due to an unset viewcontroller:
	[self setDocumentURLs:_documentURLStrings];
}

- (void)dealloc {
	_previewController = nil;
}

- (void)willMoveToSuperview:(nullable UIView *)newSuperview {
    if (newSuperview != nil) {
        [self setDocumentURLs:_documentURLStrings];
    }
}

- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller {
#ifdef IS_APPDOO_PREVIEW
    return 0;
#else
	return _documentURLStrings.count;
#endif
}


- (id <QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index {
    #ifdef IS_APPDOO_PREVIEW
        return nil;
    #endif
	NSInteger c = _documentURLStrings.count;
	if (index < 0 || index > c-1) {
		return nil;
	}
	//index = 0;
	
	NSString * urlString = _documentURLStrings[index];
    // we'll have to write the document's contents to a cache file since QLPreviewController can only handle file urls:
	if ([urlString hasPrefix:@"file:"]) {
        // we won't play any media files in the preview app but just show a placeholder image instead:
        /*
        if ([ProjectResourcesCache sharedCache] != nil) {
            if([[ProjectResourcesCache sharedCache] resourceWithIDIsCached:[urlString substringFromIndex:5]]) {
                NSString *filename = [urlString substringFromIndex:5];
                NSData * data = [[ProjectResourcesCache sharedCache] dataForResourceID:filename];
                
                NSArray * paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
                NSString * cachePath = [paths objectAtIndex:0];
                NSString * cacheFile = [cachePath stringByAppendingPathComponent:filename];
                [data writeToFile:cacheFile atomically:NO];
                
                NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@",cacheFile]];
                if (![[NSFileManager defaultManager] isReadableFileAtPath:url.path]) {
                    //NSSLog(@"ERROR: cached data url not readable !!!");
                }
                return url;
            }
            */
            /*
            NSString * fileID = [[Prototype sharedInstance] resourceIDForFilename:[urlString substringFromIndex:5]];
            if([[ProjectResourcesCache sharedCache] resourceWithIDIsCached:fileID]) {
                NSData * data = [[ProjectResourcesCache sharedCache] dataForResourceID:fileID];
                
                NSArray * paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
                NSString * cacheFile = [[paths objectAtIndex:0] stringByAppendingPathComponent:fileID];
                
                NSError *cacheError = nil;
                //[data writeToFile:cacheFile options:NSDataWritingAtomic error:&cacheError];
                [data writeToFile:cacheFile atomically:NO];
                if(!cacheError) {
                    NSURL *url = [NSURL URLWithString:cacheFile];
                    NSLog(@"cached data url: %@",fileID);
                    if (![[NSFileManager defaultManager] isReadableFileAtPath:url.path]) {
                        NSLog(@"ERROR: cached data url not readable !!!");
                    }
                    return url;
                } else {
                    NSLog(@"ERROR: resource could not be written to file cache.");
                    return nil;
                }
            } else {
                NSLog(@"ERROR: resource not found in memory cache.");
                return nil;
            }
        }
        */
		//NSString * filename = [urlString substringFromIndex:5];
		NSString * path = GetFileURLFromString(urlString).path;
		//[[NSBundle mainBundle] pathForResource:filename ofType:nil];
        if (path) {
            return [NSURL fileURLWithPath:path];
        }
	} else if ([urlString hasPrefix:@"http:"] || [urlString hasPrefix:@"https:"]) {
		
        if (!_pathsByIndex) {
            _pathsByIndex = @{}.mutableCopy;
        }
		NSString * cacheFilePath = _pathsByIndex[[NSNumber numberWithInteger:index]];
		NSString *dummyFilePath = nil;
		if (!cacheFilePath) {
			NSArray * cachePathList = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
			NSString * cachePath    = [cachePathList objectAtIndex:0];
			NSString * cacheFilePath = [cachePath stringByAppendingPathComponent:[urlString sha1]];
			if (urlString.pathExtension.length) {
				cacheFilePath = [cacheFilePath stringByAppendingPathExtension:urlString.pathExtension];
			}
			_pathsByIndex[[NSNumber numberWithInteger:index]] = cacheFilePath;
			dummyFilePath = [cachePath stringByAppendingPathComponent:@"placeholder.jpg"];
		}
		[self createDummyDocumentAtPath:dummyFilePath];
        
		if ([[NSFileManager defaultManager] fileExistsAtPath:cacheFilePath isDirectory:nil]) {
			return [NSURL fileURLWithPath:cacheFilePath];
		}
		
        if (!_requestsByURLString) {
            _requestsByURLString = @{}.mutableCopy;
        }
        if (_requestsByURLString[urlString]) {
            //NSLog(@"ERROR: no valid url");
            return nil;
        }
		//NSLog(@"urlString: %@",urlString);
		//NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
		NSURLRequest * request = [NSURLRequest
								  requestWithURL:[NSURL URLWithString:urlString]
								  cachePolicy:NSURLRequestReturnCacheDataElseLoad
								  timeoutInterval:5.0];
		_requestsByURLString[urlString] = request;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
		
		[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
			
			if (connectionError || !data) return;
			if (!self.previewController) return;
			
			[data writeToFile:cacheFilePath atomically:NO];
			[_requestsByURLString removeObjectForKey:urlString];
			if([self previewController:self.previewController previewItemAtIndex:index] != nil) {
				[self.previewController reloadData];
			}
			
		}];
#pragma GCC diagnostic pop
        if(dummyFilePath) {
            return [NSURL fileURLWithPath:dummyFilePath];
        }
	}
    //NSLog(@"ERROR: no valid document");
	return nil;

}

- (void)createDummyDocumentAtPath:(NSString*)path {
	if (!path || [[NSFileManager defaultManager] isReadableFileAtPath:path]) {
		return;
	}
	CGSize size = CGSizeMake(1, 1);
	UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
	//[[UIColor redColor] setFill];
	//UIRectFill(CGRectMake(0, 0, size.width, size.height));
	UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
	UIGraphicsEndImageContext();
	[UIImagePNGRepresentation(image) writeToFile:path atomically:YES];
}

- (void)setDocumentURLs:(id)values {
#ifdef IS_APPDOO_PREVIEW
    UIImage *placeholderImage = [UIImage imageNamed:@"PlaceholderImage"];
    if (!self.placeholderImageView) {
        self.placeholderImageView = [[UIImageView alloc] initWithImage:placeholderImage];
    } else {
        self.placeholderImageView.image = placeholderImage;
    }
    self.placeholderImageView.frame = CGRectMake(0, 0, placeholderImage.size.width, placeholderImage.size.height);
    self.placeholderImageView.center = self.center;
    self.placeholderImageView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleBottomMargin|UIViewAutoresizingFlexibleLeftMargin;
    [self addSubview:self.placeholderImageView];
    return;
#endif

	if ([values isKindOfClass:[NSString class]]) {
		_documentURLStrings = [((NSString *)values) componentsSeparatedByString:@"\n"];
	} else if ([values isKindOfClass:[NSArray class]] && [values count] > 0) {
		_documentURLStrings = values;
	} else {
		return;
	}
#ifdef IS_APPDOO_PREVIEW
    NSMutableArray *cachedDocumentURLStrings = [NSMutableArray array];
    for (NSString *urlString in _documentURLStrings) {
        if ([urlString hasPrefix:@"file:"]) {
            if ([ProjectResourcesCache sharedCache] != nil) {
                if([[ProjectResourcesCache sharedCache] resourceWithIDIsCached:[urlString substringFromIndex:5]]) {
                    [cachedDocumentURLStrings addObject:urlString];
                } else {
                    NSString * fileID = [[Prototype sharedInstance] resourceIDForFilename:[urlString substringFromIndex:5]];
                    if (fileID != nil) {
                        [cachedDocumentURLStrings addObject:[NSString stringWithFormat:@"file:%@",fileID]];
                    }
                }
            }
        }
    }
    _documentURLStrings = (NSArray*)cachedDocumentURLStrings;
#endif
    if (!self.previewController) {
        QLPreviewController * preview = [[QLPreviewController alloc] init];
        self.previewController = preview;
    }
	if(!self.viewController) {
#ifdef IS_APPDOO_PREVIEW
        if (!self.previewController.view.superview) {
            //set the frame from the parent view
            CGFloat w = self.frame.size.width;
            CGFloat h = self.frame.size.height;
            self.previewController.view.frame = CGRectMake(0, 0, w, h);
            self.previewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
            [self addSubview:self.previewController.view];
        }
#else
		return;
#endif
	}
	if (self.viewController && !self.previewController.parentViewController) {
		[self.viewController addChildViewController:self.previewController];
		//set the frame from the parent view
		CGFloat w = self.frame.size.width;
		CGFloat h = self.frame.size.height;
		self.previewController.view.frame = CGRectMake(0, 0, w, h);
		self.previewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
		if (!self.previewController.view.superview) {
            [self.viewController.view addSubview:self.previewController.view];
            [self.previewController didMoveToParentViewController:self.viewController];
		}
		//save a reference to the preview controller in an ivar
	}
    
	self.previewController.dataSource = self;
	self.previewController.delegate = self;
	[self.previewController reloadData];
}

@end
