/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#import "WXImageComponent.h"
#import "WXHandlerFactory.h"
#import "WXComponent_internal.h"
#import "WXImgLoaderProtocol.h"
#import "WXLayer.h"
#import "WXType.h"
#import "WXConvert.h"
#import "WXURLRewriteProtocol.h"
#import "WXRoundedRect.h"
#import "UIBezierPath+Weex.h"
#import "WXSDKEngine.h"
#import "WXUtility.h"
#import "WXAssert.h"
#import "WXConfigCenterProtocol.h"
#import "WXSDKEngine.h"
#import <pthread/pthread.h>
#import "WXMonitor.h"
#import "WXSDKInstance_performance.h"

@interface WXImageView : UIImageView

@end

@implementation WXImageView

+ (Class)layerClass
{
    return [WXLayer class];
}

@end

static dispatch_queue_t WXImageUpdateQueue;

@interface WXImageComponent ()
{
    BOOL _shouldUpdateImage;
    BOOL _mainImageSuccess;
}

@property (atomic, strong) NSString *src;
@property (atomic, strong) NSString *darkSchemeSrc;
@property (atomic, strong) NSString *lightSchemeSrc;
@property (atomic, strong) NSString *placeholdSrc;
@property (atomic, strong) NSString *darkSchemePlaceholderSrc;
@property (atomic, strong) NSString *lightSchemePlaceholderSrc;
@property (nonatomic, assign) CGFloat blurRadius;
@property (nonatomic, assign) UIViewContentMode resizeMode;
@property (nonatomic, assign) WXImageQuality imageQuality;
@property (nonatomic, assign) WXImageSharp imageSharp;
@property (nonatomic, strong) UIImage *image;
@property (nonatomic, strong) id<WXImageOperationProtocol> imageOperation;
@property (nonatomic, strong) id<WXImageOperationProtocol> placeholderOperation;
@property (nonatomic) BOOL imageLoadEvent;
@property (nonatomic) BOOL imageDownloadFinish;
@property (nonatomic) BOOL downloadImageWithURL;
@property (nonatomic, strong) NSString* preUrl;

@end

@implementation WXImageComponent

WX_EXPORT_METHOD(@selector(save:))

- (instancetype)initWithRef:(NSString *)ref type:(NSString *)type styles:(NSDictionary *)styles attributes:(NSDictionary *)attributes events:(NSArray *)events weexInstance:(WXSDKInstance *)weexInstance
{
    if (self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance]) {
        _shouldUpdateImage = NO;
        _async = YES;
        if (!WXImageUpdateQueue) {
            WXImageUpdateQueue = dispatch_queue_create("com.taobao.weex.ImageUpdateQueue", DISPATCH_QUEUE_SERIAL);
        }
        
        if (attributes[@"src"]) {
            self.src = [[WXConvert NSString:attributes[@"src"]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
        } else {
            WXLogWarning(@"image src is nil");
        }
        if (attributes[@"darkSchemeSrc"]) {
            self.darkSchemeSrc = [[WXConvert NSString:attributes[@"darkSchemeSrc"]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
        }
        if (attributes[@"lightSchemeSrc"]) {
            self.lightSchemeSrc = [[WXConvert NSString:attributes[@"lightSchemeSrc"]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
        }
        
        [self configPlaceHolder:attributes];
        
        NSString *resizeMode = attributes[@"resize"];
        if (!resizeMode) {
            resizeMode = styles[@"resizeMode"];
        }
        _resizeMode = [WXConvert UIViewContentMode:resizeMode];
        
        _imageQuality = WXImageQualityNone;
        if (styles[@"quality"]) {
            _imageQuality = [WXConvert WXImageQuality:styles[@"quality"]];
        }
        if (attributes[@"quality"]) {
            _imageQuality = [WXConvert WXImageQuality:attributes[@"quality"]];
        }
        
        _downloadImageWithURL = YES;
        if (attributes[@"compositing"]) {
            _downloadImageWithURL = [WXConvert BOOL:attributes[@"compositing"]];
        }
        
        [self configFilter:styles needUpdate:NO];
        
        _imageSharp = [WXConvert WXImageSharp:styles[@"sharpen"]];
        _imageLoadEvent = NO;
        _imageDownloadFinish = NO;
    }
    
    return self;
}

- (void)configPlaceHolder:(NSDictionary*)attributes
{
    if (attributes[@"placeHolder"] || attributes[@"placeholder"]) {
        self.placeholdSrc = [[WXConvert NSString:attributes[@"placeHolder"]?:attributes[@"placeholder"]]stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    }
    if (attributes[@"darkSchemePlaceholder"]) {
        self.darkSchemePlaceholderSrc = [[WXConvert NSString:attributes[@"darkSchemePlaceholder"]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    }
    if (attributes[@"lightSchemePlaceholder"]) {
        self.lightSchemePlaceholderSrc = [[WXConvert NSString:attributes[@"lightSchemePlaceholder"]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    }
}

- (void)configFilter:(NSDictionary *)styles needUpdate:(BOOL)needUpdate
{
    if (styles[@"filter"]) {
        NSString *filter = styles[@"filter"];
        
        NSString *pattern = @"blur\\((\\d+)(px)?\\)";
        NSError *error = nil;
        NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern
                                                                               options:NSRegularExpressionCaseInsensitive
                                                                                 error:&error];
        NSArray *matches = [regex matchesInString:filter options:0 range:NSMakeRange(0, filter.length)];
        if (matches && matches.count > 0) {
            NSTextCheckingResult *match = matches[matches.count - 1];
            NSRange matchRange = [match rangeAtIndex:1];
            NSString *matchString = [filter substringWithRange:matchRange];
            if (matchString && matchString.length > 0) {
                _blurRadius = [matchString doubleValue];
                if (needUpdate) {
                    [self updateImage];
                }
            }
        }
    }
}

- (void)save:(WXKeepAliveCallback)resultCallback
{
    NSDictionary *info = [NSBundle mainBundle].infoDictionary;
    if(!info[@"NSPhotoLibraryUsageDescription"]) {
        if (resultCallback) {
            resultCallback(@{
                             @"success" : @(false),
                             @"errorDesc": @"This maybe crash above iOS 10 because it attempted to access privacy-sensitive data without a usage description.  The app's Info.plist must contain an NSPhotoLibraryUsageDescription key with a string value explaining to the user how the app uses this data."
                             }, NO);
        }
        return ;
    }
    
    // iOS 11 needs a NSPhotoLibraryUsageDescription key for permission
    if (WX_SYS_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0")) {
        if (!info[@"NSPhotoLibraryAddUsageDescription"]) {
            if (resultCallback) {
                resultCallback(@{
                                 @"success" : @(false),
                                 @"errorDesc": @"This maybe crash above iOS 11 because it attempted to save image without a usage description.  The app's Info.plist must contain an NSPhotoLibraryAddUsageDescription key with a string value explaining to the user how the app uses this data."
                                 }, NO);
            }
            return;
        }
    }
    
    if (![self isViewLoaded]) {
        if (resultCallback) {
            resultCallback(@{@"success": @(false),
                             @"errorDesc":@"the image is not ready"}, NO);
        }
        return;
    }
    UIImageView * imageView = (UIImageView*)self.view;
    if (!resultCallback) {
        // there is no need to callback any result;
        UIImageWriteToSavedPhotosAlbum(imageView.image, nil, nil, NULL);
    }else {
        UIImageWriteToSavedPhotosAlbum(imageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), (void*)CFBridgingRetain(resultCallback));
    }
}

// the callback for PhotoAlbum.
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
    if (!contextInfo) {
        return;
    }
    NSMutableDictionary * callbackResult = [NSMutableDictionary new];
    BOOL success = false;
    if (!error) {
        success = true;
    } else {
        [callbackResult setObject:[error description] forKey:@"errorDesc"];
    }
    if (contextInfo) {
        [callbackResult setObject:@(success) forKey:@"success"];
        ((__bridge WXKeepAliveCallback)contextInfo)(callbackResult, NO);
        CFRelease(contextInfo);
    }
}

- (UIView *)loadView
{
    return [[WXImageView alloc] init];
}

- (void)addEvent:(NSString *)eventName {
    if ([eventName isEqualToString:@"load"]) {
        _imageLoadEvent = YES;
    }
}

- (void)removeEvent:(NSString *)eventName {
    if ([eventName isEqualToString:@"load"]) {
        _imageLoadEvent = NO;
    }
}

- (void)updateStyles:(NSDictionary *)styles
{
    if (styles[@"quality"]) {
        _imageQuality = [WXConvert WXImageQuality:styles[@"quality"]];
        [self updateImage];
    }
    
    if (styles[@"sharpen"]) {
        _imageSharp = [WXConvert WXImageSharp:styles[@"sharpen"]];
        [self updateImage];
    }
    [self configFilter:styles needUpdate:YES];
}

- (void)dealloc
{
    [self cancelImage];
}

- (void)updateAttributes:(NSDictionary *)attributes
{
    if (attributes[@"darkSchemeSrc"]) {
        self.darkSchemeSrc = [[WXConvert NSString:attributes[@"darkSchemeSrc"]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    }
    if (attributes[@"lightSchemeSrc"]) {
        self.lightSchemeSrc = [[WXConvert NSString:attributes[@"lightSchemeSrc"]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    }
    if (attributes[@"src"]) {
        [self setImageSrc:[[WXConvert NSString:attributes[@"src"]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
    }
    if (attributes[@"quality"]) {
        _imageQuality = [WXConvert WXImageQuality:attributes[@"quality"]];
        [self updateImage];
    }
    
    [self configPlaceHolder:attributes];
    
    if (attributes[@"resize"]) {
        _resizeMode = [WXConvert UIViewContentMode:attributes[@"resize"]];
        self.view.contentMode = _resizeMode;
    }
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    UIImageView *imageView = (UIImageView *)self.view;
    imageView.contentMode = _resizeMode;
    imageView.userInteractionEnabled = YES;
    imageView.clipsToBounds = YES;
    imageView.exclusiveTouch = YES;
    imageView.isAccessibilityElement = YES;
    
    [self _clipsToBounds];
    
    [self updateImage];
}

- (void)schemeDidChange:(NSString*)scheme
{
    [super schemeDidChange:scheme];
    if (_view) {
        if (self.darkSchemeSrc || self.darkSchemePlaceholderSrc ||
            self.lightSchemeSrc || self.lightSchemePlaceholderSrc) {
            [self updateImage];
        }
    }
}

- (BOOL)_needsDrawBorder
{
    return NO;
}

- (void)_resetNativeBorderRadius
{
    if (_borderTopLeftRadius == _borderTopRightRadius && _borderTopRightRadius == _borderBottomLeftRadius && _borderBottomLeftRadius == _borderBottomRightRadius)
    {
        WXRoundedRect *borderRect = [[WXRoundedRect alloc] initWithRect:self.calculatedFrame topLeft:_borderTopLeftRadius topRight:_borderTopRightRadius bottomLeft:_borderBottomLeftRadius bottomRight:_borderBottomRightRadius];
        _layer.cornerRadius = borderRect.radii.topLeft;
        return;
    }
    [self _clipsToBounds];
}

- (BOOL)needsDrawRect
{
    if (_isCompositingChild) {
        return YES;
    } else {
        return NO;
    }
}

- (UIImage *)drawRect:(CGRect)rect;
{
    if (!self.image) {
        [self updateImage];
        return nil;
    }
    
    WXRoundedRect *borderRect = [[WXRoundedRect alloc] initWithRect:rect topLeft:_borderTopLeftRadius topRight:_borderTopRightRadius bottomLeft:_borderBottomLeftRadius bottomRight:_borderBottomRightRadius];

    WXRadii *radii = borderRect.radii;    
    if ([radii hasBorderRadius]) {
        CGFloat topLeft = radii.topLeft, topRight = radii.topRight, bottomLeft = radii.bottomLeft, bottomRight = radii.bottomRight;
        UIBezierPath *bezierPath = [UIBezierPath wx_bezierPathWithRoundedRect:rect topLeft:topLeft topRight:topRight bottomLeft:bottomLeft bottomRight:bottomRight];
        [bezierPath addClip];
    }
    return self.image;
}

- (void)viewWillUnload
{
    [super viewWillUnload];
    [self cancelImage];
    _image = nil;
}

- (void)_frameDidCalculated:(BOOL)isChanged
{
    [super _frameDidCalculated:isChanged];
    
    if ([self isViewLoaded] && isChanged) {
        __weak typeof(self) weakSelf = self;
        WXPerformBlockOnMainThread(^{
            [weakSelf _clipsToBounds];
        });
    }
}

- (void)setImageSrc:(NSString*)src
{
    if ([src isEqualToString:self.src]) {
        // if image src is equal to then ignore it.
        return;
    }
    self.src = src;
    _imageDownloadFinish = NO;
    ((UIImageView*)self.view).image = nil;
    
    [self updateImage];
}

- (void)layoutDidFinish
{
    [super layoutDidFinish];
    if (_shouldUpdateImage) {
        [self updateImage];
        _shouldUpdateImage = NO;
    }
}

- (NSString*)chooseImage:(NSString*)src lightSrc:(NSString*)lightSrc darkSrc:(NSString*)darkSrc
{
    if ([self.weexInstance isDarkScheme]) {
        if (darkSrc) {
            return darkSrc;
        }
        else {
            return src;
        }
    }
    else if (lightSrc) {
        return lightSrc;
    }
    else {
        return src;
    }
}

- (void)updateImage
{
    if (CGSizeEqualToSize(_view.frame.size, CGSizeZero)) {
        _shouldUpdateImage = YES;
        return;
    }
    
    NSString* choosedSrc = [self chooseImage:self.src lightSrc:self.lightSchemeSrc darkSrc:self.darkSchemeSrc];
    NSString* choosedPlaceholder = [self chooseImage:self.placeholdSrc lightSrc:self.lightSchemePlaceholderSrc darkSrc:self.darkSchemePlaceholderSrc];
    
    __weak typeof(self) weakSelf = self;
    if (_downloadImageWithURL && [[self imageLoader] respondsToSelector:@selector(setImageViewWithURL:url:placeholderImage:options:progress:completed:)]) {
        _mainImageSuccess = NO;
        
        NSString *newURL = nil;
        if (choosedPlaceholder) {
            newURL = [choosedPlaceholder copy];
            WX_REWRITE_URL(choosedPlaceholder, WXResourceTypeImage, self.weexInstance)
            NSDictionary* extInfo = @{@"instanceId":[self _safeInstanceId], @"pageURL": self.weexInstance.scriptURL ?: @""};
            [[self imageLoader] setImageViewWithURL:(UIImageView*)self.view url:[NSURL URLWithString:newURL] placeholderImage:nil options:extInfo progress:nil completed:^(UIImage *image, NSError *error, WXImageLoaderCacheType cacheType, NSURL *imageURL) {
                /* We cannot rely on image library even if we call setImage with placeholer before calling setImage with real url.
                 The placeholder image may be downloaded and decoded after the real url, so finally we show the placeholder image by wrong. */
                __strong typeof(weakSelf) strongSelf = weakSelf;
                if (strongSelf) {
                    UIImageView *imageView = (UIImageView *)strongSelf.view;
                    if (imageView && imageView.image == image && strongSelf->_mainImageSuccess) {
                        // reload image with main image url
                        NSString* newURL = [choosedSrc copy];
                        WX_REWRITE_URL(choosedSrc, WXResourceTypeImage, strongSelf.weexInstance)
                        NSDictionary *userInfo = @{@"imageQuality":@(strongSelf.imageQuality), @"imageSharp":@(strongSelf.imageSharp),  @"blurRadius":@(strongSelf.blurRadius), @"instanceId":[strongSelf _safeInstanceId], @"pageURL": strongSelf.weexInstance.scriptURL ?: @""};
                        [[strongSelf imageLoader] setImageViewWithURL:imageView url:[NSURL URLWithString:newURL] placeholderImage:nil options:userInfo progress:nil completed:^(UIImage *image, NSError *error, WXImageLoaderCacheType cacheType, NSURL *imageURL) {
                            WXLogInfo(@"Image re-requested because placeholder may override main image. %@", imageURL);
                        }];
                    }
                }
            }];
        }
        newURL = [choosedSrc copy];
        if ([newURL length] == 0) {
            return;
        }
        WX_REWRITE_URL(choosedSrc, WXResourceTypeImage, self.weexInstance)
        NSDictionary *userInfo = @{@"imageQuality":@(self.imageQuality), @"imageSharp":@(self.imageSharp),  @"blurRadius":@(self.blurRadius), @"instanceId":[self _safeInstanceId], @"pageURL": self.weexInstance.scriptURL ?: @""};
        [[self imageLoader] setImageViewWithURL:(UIImageView*)self.view url:[NSURL URLWithString:newURL] placeholderImage:nil options:userInfo progress:^(NSInteger receivedSize, NSInteger expectedSize) {
            // progress when loading image
        } completed:^(UIImage *image, NSError *error, WXImageLoaderCacheType cacheType, NSURL *imageURL) {
            __strong typeof(weakSelf) strongSelf = weakSelf;
            if (strongSelf == nil) {
                return;
            }
            
            strongSelf.imageDownloadFinish = YES;
            if (error) {
                // log error message for error
                WXLogError(@"Error downloading image: %@, detail:%@", imageURL.absoluteString, [error localizedDescription]);
                
                // retry set placeholder, maybe placeholer image can be downloaded
                if (choosedPlaceholder) {
                    NSString *newURL = [choosedPlaceholder copy];
                    WX_REWRITE_URL(choosedPlaceholder, WXResourceTypeImage, strongSelf.weexInstance)
                    [[strongSelf imageLoader] setImageViewWithURL:(UIImageView*)strongSelf.view
                                                              url:[NSURL URLWithString:newURL]
                                                 placeholderImage:nil
                                                          options:@{@"instanceId":[strongSelf _safeInstanceId], @"pageURL": strongSelf.weexInstance.scriptURL ?: @""}
                                                         progress:nil
                                                        completed:nil];
                    return;
                }
                strongSelf->_mainImageSuccess = NO;
            }
            else {
                strongSelf->_mainImageSuccess = YES;
            }
            UIImageView *imageView = (UIImageView *)strongSelf.view;
            if (imageView && imageView.image != image) {
                imageView.image = image;
            }
            if (strongSelf.imageLoadEvent) {
                NSMutableDictionary *sizeDict = [NSMutableDictionary new];
                sizeDict[@"naturalWidth"] = @0;
                sizeDict[@"naturalHeight"] = @0;
                if (!error) {
                    sizeDict[@"naturalWidth"] = @(image.size.width * image.scale);
                    sizeDict[@"naturalHeight"] = @(image.size.height * image.scale);
                } else {
                    [sizeDict setObject:[error description]?:@"" forKey:@"errorDesc"];
                }
                [strongSelf fireEvent:@"load" params:@{ @"success": error? @false : @true,@"size":sizeDict}];
            }
            NSString* curUrl = imageURL.absoluteString;
            //check view/img size
            if (!error && image && imageView && ![curUrl isEqualToString:self.preUrl]) {
                self.preUrl = curUrl;
                CGFloat screenScale = [[UIScreen mainScreen] scale];
                double imageSize = image.size.width*image.scale  * image.size.height*image.scale;
                double viewSize = imageView.frame.size.height *screenScale*  imageView.frame.size.width * screenScale;
                CGFloat sizeRatio = imageSize/viewSize;
                
                //minDiffSize limt 40*40
                if (sizeRatio>1.2 && (imageSize-viewSize) > 1600) {
                    self.weexInstance.performance.imgWrongSizeNum++;
                    [self.weexInstance.apmInstance updateDiffStats:KEY_PAGE_STATS_WRONG_IMG_SIZE_COUNT withDiffValue:1];
                }
                    
                if (image.size.width* image.scale > 720 && image.size.height * image.scale> 1080) {
                    [self.weexInstance.apmInstance updateDiffStats:KEY_PAGE_STATS_LARGE_IMG_COUNT withDiffValue:1];
                }
            }
        }];
    } else {
        dispatch_async(WXImageUpdateQueue, ^{
             __strong typeof(weakSelf) strongSelf = weakSelf;
            if (strongSelf == nil) {
                return;
            }
            
            [strongSelf cancelImage];

            void(^downloadFailed)(NSString *, NSError *) = ^void(NSString *url, NSError *error) {
                weakSelf.imageDownloadFinish = YES;
                WXLogError(@"Error downloading image: %@, detail:%@", url, [error localizedDescription]);
            };

            [strongSelf updatePlaceHolderWithFailedBlock:downloadFailed];
            [strongSelf updateContentImageWithFailedBlock:downloadFailed];

            if (!choosedSrc && !choosedPlaceholder) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    strongSelf.layer.contents = nil;
                    strongSelf.imageDownloadFinish = YES;
                    [strongSelf readyToRender];
                });
            }
        });
    }
}

- (void)updatePlaceHolderWithFailedBlock:(void(^)(NSString *, NSError *))downloadFailedBlock
{
    NSString* choosedPlaceholder = [self chooseImage:self.placeholdSrc lightSrc:self.lightSchemePlaceholderSrc darkSrc:self.darkSchemePlaceholderSrc];
    
    if ([WXUtility isBlankString:choosedPlaceholder]) {
        return;
    }
    
    WXLogDebug(@"Updating image, component:%@, placeholder:%@ ", self.ref, choosedPlaceholder);
    NSString *newURL = [choosedPlaceholder copy];
    WX_REWRITE_URL(choosedPlaceholder, WXResourceTypeImage, self.weexInstance)
    
    __weak typeof(self) weakSelf = self;
    self.placeholderOperation = [[self imageLoader] downloadImageWithURL:newURL imageFrame:self.calculatedFrame
                                        userInfo:@{@"instanceId":[self _safeInstanceId], @"pageURL": self.weexInstance.scriptURL ?: @""}
                                        completed:^(UIImage *image, NSError *error, BOOL finished)
    {
        dispatch_async(dispatch_get_main_queue(), ^{
            __strong typeof(self) strongSelf = weakSelf;
            if (strongSelf == nil) {
                return;
            }
            UIImage *viewImage = ((UIImageView *)strongSelf.view).image;
            if (error) {
                downloadFailedBlock(choosedPlaceholder, error);
                if ([strongSelf isViewLoaded] && !viewImage) {
                    ((UIImageView *)(strongSelf.view)).image = nil;
                    [strongSelf readyToRender];
                }
                return;
            }
            
            NSString* currentPlaceholder = [strongSelf chooseImage:strongSelf.placeholdSrc lightSrc:strongSelf.lightSchemePlaceholderSrc darkSrc:strongSelf.darkSchemePlaceholderSrc];
            if (![choosedPlaceholder isEqualToString:currentPlaceholder]) {
                return;
            }
            
            if ([strongSelf isViewLoaded] && !viewImage) {
                ((UIImageView *)strongSelf.view).image = image;
                strongSelf.imageDownloadFinish = YES;
                [strongSelf readyToRender];
            } else if (strongSelf->_isCompositingChild) {
                strongSelf->_image = image;
                strongSelf.imageDownloadFinish = YES;
            }
        });
    }];
}

- (void)updateContentImageWithFailedBlock:(void(^)(NSString *, NSError *))downloadFailedBlock
{
    NSString* choosedSrc = [self chooseImage:self.src lightSrc:self.lightSchemeSrc darkSrc:self.darkSchemeSrc];
    
    if ([WXUtility isBlankString:choosedSrc]) {
        WXLogError(@"image src is empty");
        return;
    }
    
    WXLogDebug(@"Updating image:%@, component:%@", choosedSrc, self.ref);
    NSDictionary *userInfo = @{@"imageQuality":@(self.imageQuality), @"imageSharp":@(self.imageSharp), @"blurRadius":@(self.blurRadius), @"instanceId":[self _safeInstanceId], @"pageURL": self.weexInstance.scriptURL ?: @""};
    NSString * newURL = [choosedSrc copy];
    WX_REWRITE_URL(choosedSrc, WXResourceTypeImage, self.weexInstance)
    __weak typeof(self) weakSelf = self;
    weakSelf.imageOperation = [[weakSelf imageLoader] downloadImageWithURL:newURL imageFrame:weakSelf.calculatedFrame userInfo:userInfo completed:^(UIImage *image, NSError *error, BOOL finished) {
        dispatch_async(dispatch_get_main_queue(), ^{
            __strong typeof(self) strongSelf = weakSelf;
            if (strongSelf == nil) {
                return;
            }
            
            if (strongSelf.imageLoadEvent) {
                NSMutableDictionary *sizeDict = [NSMutableDictionary new];
                sizeDict[@"naturalWidth"] = @0;
                sizeDict[@"naturalHeight"] = @0;
                if (!error) {
                    sizeDict[@"naturalWidth"] = @(image.size.width * image.scale);
                    sizeDict[@"naturalHeight"] = @(image.size.height * image.scale);
                } else {
                    [sizeDict setObject:[error description]?:@"" forKey:@"errorDesc"];
                }
                [strongSelf fireEvent:@"load" params:@{ @"success": error? @false : @true,@"size":sizeDict}];
            }
            if (error) {
                downloadFailedBlock(choosedSrc, error);
                [strongSelf readyToRender];
                return ;
            }
            
            NSString* currentSrc = [strongSelf chooseImage:strongSelf.src lightSrc:strongSelf.lightSchemeSrc darkSrc:strongSelf.darkSchemeSrc];
            if (![choosedSrc isEqualToString:currentSrc]) {
                return ;
            }
            
            if ([strongSelf isViewLoaded]) {
                strongSelf.imageDownloadFinish = YES;
                ((UIImageView *)strongSelf.view).image = image;
                [strongSelf readyToRender];
            } else if (strongSelf->_isCompositingChild) {
                strongSelf.imageDownloadFinish = YES;
                strongSelf->_image = image;
                [strongSelf setNeedsDisplay];
            }
        });
    }];
}

- (NSString*) _safeInstanceId
{
    return self.weexInstance.instanceId ? : @"unknown";
}

- (void)readyToRender
{
    // when image download completely (success or failed)
    if (self.weexInstance.trackComponent && _imageDownloadFinish) {
        [super readyToRender];
    }
}

- (void)cancelImage
{
    if ([[self imageLoader] respondsToSelector:@selector(cancelCurrentImageLoad:)]) {
        [[self imageLoader] cancelCurrentImageLoad:(UIImageView*)_view];
    }
    _shouldUpdateImage = NO;
    [_imageOperation cancel];
    _imageOperation = nil;
    [_placeholderOperation cancel];
    _placeholderOperation = nil;
}

- (id<WXImgLoaderProtocol>)imageLoader
{
    static id<WXImgLoaderProtocol> imageLoader;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        imageLoader = [WXHandlerFactory handlerForProtocol:@protocol(WXImgLoaderProtocol)];
    });
    return imageLoader;
}

- (void)_clipsToBounds
{
    WXAssertMainThread();
    WXRoundedRect *borderRect = [[WXRoundedRect alloc] initWithRect:self.view.bounds topLeft:_borderTopLeftRadius topRight:_borderTopRightRadius bottomLeft:_borderBottomLeftRadius bottomRight:_borderBottomRightRadius];
    // here is computed radii, do not use original style
    WXRadii *radii = borderRect.radii;
    
    if ([radii radiusesAreEqual]) {
        return;
    }
    
    CGFloat topLeft = radii.topLeft, topRight = radii.topRight, bottomLeft = radii.bottomLeft, bottomRight = radii.bottomRight;
    
    // clip to border radius
    UIBezierPath *bezierPath = [UIBezierPath wx_bezierPathWithRoundedRect:self.view.bounds topLeft:topLeft topRight:topRight bottomLeft:bottomLeft bottomRight:bottomRight];
    
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.path = bezierPath.CGPath;
    self.layer.mask = shapeLayer;
    self.layer.cornerRadius = 0;
}

#ifdef UITEST
- (NSString *)description
{
    NSString *superDescription = super.description;
    NSRange semicolonRange = [superDescription rangeOfString:@";"];
    NSString *replacement = [NSString stringWithFormat:@"; imageSrc: %@; imageQuality: %@; imageSharp: %@; ",_imageSrc,_imageQuality,_imageSharp];
    return [superDescription stringByReplacingCharactersInRange:semicolonRange withString:replacement];
}
#endif

@end
