/*
* Copyright (C) 2020 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#import "config.h"
#import "QuickLookThumbnailLoader.h"

#if HAVE(QUICKLOOK_THUMBNAILING)

#import <wtf/FileSystem.h>

#import "QuickLookThumbnailingSoftLink.h"

@implementation WKQLThumbnailQueueManager 

- (instancetype)init
{
    self = [super init];
    if (self)
        _queue = [[NSOperationQueue alloc] init];
    return self;
}

- (void)dealloc
{
    [_queue release];
    [super dealloc];
}

+ (WKQLThumbnailQueueManager *)sharedInstance
{
    static WKQLThumbnailQueueManager *sharedInstance = [[WKQLThumbnailQueueManager alloc] init];
    return sharedInstance;
}

@end

@interface WKQLThumbnailLoadOperation ()
@property (atomic, readwrite, getter=isExecuting) BOOL executing;
@property (atomic, readwrite, getter=isFinished) BOOL finished;
@end

@implementation WKQLThumbnailLoadOperation {
    RetainPtr<NSURL> _filePath;
    RetainPtr<NSString> _identifier;
    RetainPtr<NSFileWrapper> _fileWrapper;
    RetainPtr<CocoaImage> _thumbnail;
    BOOL _shouldWrite;
}

- (instancetype)initWithAttachment:(NSFileWrapper *)fileWrapper identifier:(NSString *)identifier
{
    if (self = [super init]) {
        _fileWrapper = fileWrapper;
        _identifier = adoptNS([identifier copy]);
        _shouldWrite = YES;
    }
    return self;
}

- (instancetype)initWithURL:(NSString *)fileURL identifier:(NSString *)identifier
{
    if (self = [super init]) {
        _identifier = adoptNS([identifier copy]);
        _filePath = [NSURL fileURLWithPath:fileURL];
    }
    return self;
}

- (void)start
{
    self.executing = YES;

    if (_shouldWrite) {
        NSString *temporaryDirectory = FileSystem::createTemporaryDirectory(@"QLTempFileData");

        NSString *filePath = [temporaryDirectory stringByAppendingPathComponent:[_fileWrapper preferredFilename]];
        NSFileWrapperWritingOptions options = 0;
        NSError *error = nil;
        
        auto fileURLPath = [NSURL fileURLWithPath:filePath];

        [_fileWrapper writeToURL:fileURLPath options:options originalContentsURL:nil error:&error];
        _filePath = WTFMove(fileURLPath);
        if (error)
            return;
    }

    auto request = adoptNS([WebKit::allocQLThumbnailGenerationRequestInstance() initWithFileAtURL:_filePath.get() size:CGSizeMake(400, 400) scale:1 representationTypes:QLThumbnailGenerationRequestRepresentationTypeAll]);
    [request setIconMode:YES];
    
    [[WebKit::getQLThumbnailGeneratorClass() sharedGenerator] generateBestRepresentationForRequest:request.get() completionHandler:^(QLThumbnailRepresentation *thumbnail, NSError *error) {
        if (error)
            return;
        if (_thumbnail)
            return;
#if USE(APPKIT)
        _thumbnail = thumbnail.NSImage;
#else
        _thumbnail = thumbnail.UIImage;
#endif
        if (_shouldWrite)
            [[NSFileManager defaultManager] removeItemAtURL:_filePath.get() error:nullptr];

        self.executing = NO;
        self.finished = YES;
    }];
}

- (CocoaImage *)thumbnail
{
    return _thumbnail.get();
}

- (NSString *)identifier
{
    return _identifier.get();
}

- (BOOL)isAsynchronous
{
    return YES;
}

@synthesize executing=_executing;

- (BOOL)isExecuting
{
    @synchronized(self) {
        return _executing;
    }
}

- (void)setExecuting:(BOOL)executing
{
    @synchronized(self) {
        if (executing != _executing) {
            [self willChangeValueForKey:@"isExecuting"];
            _executing = executing;
            [self didChangeValueForKey:@"isExecuting"];
        }
    }
}

@synthesize finished=_finished;

- (BOOL)isFinished
{
    @synchronized(self) {
        return _finished;
    }
}

- (void)setFinished:(BOOL)finished
{
    @synchronized(self) {
        if (finished != _finished) {
            [self willChangeValueForKey:@"isFinished"];
            _finished = finished;
            [self didChangeValueForKey:@"isFinished"];
        }
    }
}

@end

#endif // HAVE(QUICKLOOK_THUMBNAILING)
