/*
 * 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 ()
{
    NSString * _imageSrc;
    pthread_mutex_t _imageSrcMutex;
    pthread_mutexattr_t _propertMutexAttr;
    BOOL _shouldUpdateImage;
    BOOL _mainImageSuccess;
}

@property (atomic, strong) NSString *placeholdSrc;
@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);
        }
        
        pthread_mutexattr_init(&(_propertMutexAttr));
        pthread_mutexattr_settype(&(_propertMutexAttr), PTHREAD_MUTEX_RECURSIVE);
        pthread_mutex_init(&(_imageSrcMutex), &(_propertMutexAttr));
        
        if (attributes[@"src"]) {
             pthread_mutex_lock(&(_imageSrcMutex));
            _imageSrc = [[WXConvert NSString:attributes[@"src"]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
             pthread_mutex_unlock(&(_imageSrcMutex));
        } else {
            WXLogWarning(@"image src is nil");
        }
        [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]];
    }
}

- (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];
    pthread_mutex_destroy(&(_imageSrcMutex));
    pthread_mutexattr_destroy(&_propertMutexAttr);
}

- (void)updateAttributes:(NSDictionary *)attributes
{
    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];
    
}

- (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];
        });
    }
}

- (NSString *)imageSrc
{
    pthread_mutex_lock(&(_imageSrcMutex));
    NSString * imageSrcCpy = [_imageSrc copy];
    pthread_mutex_unlock(&(_imageSrcMutex));
    
    return imageSrcCpy;
}

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

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

- (void)updateImage
{
    if (CGSizeEqualToSize(_view.frame.size, CGSizeZero)) {
        _shouldUpdateImage = YES;
        return;
    }
    __weak typeof(self) weakSelf = self;
    if (_downloadImageWithURL && [[self imageLoader] respondsToSelector:@selector(setImageViewWithURL:url:placeholderImage:options:progress:completed:)]) {
        _mainImageSuccess = NO;
        
        NSString *newURL = nil;
        if (self.placeholdSrc) {
            newURL = [self.placeholdSrc copy];
            WX_REWRITE_URL([self placeholdSrc], 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 = [[strongSelf imageSrc] copy];
                        WX_REWRITE_URL([strongSelf imageSrc], 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 = [[self imageSrc] copy];
        if ([newURL length] == 0) {
            return;
        }
        WX_REWRITE_URL([self imageSrc], 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 (strongSelf.placeholdSrc) {
                    NSString *newURL = [strongSelf.placeholdSrc copy];
                    WX_REWRITE_URL([strongSelf placeholdSrc], 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 (!strongSelf.imageSrc && !strongSelf.placeholdSrc) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    strongSelf.layer.contents = nil;
                    strongSelf.imageDownloadFinish = YES;
                    [strongSelf readyToRender];
                });
            }
        });
    }
}

- (void)updatePlaceHolderWithFailedBlock:(void(^)(NSString *, NSError *))downloadFailedBlock
{
    NSString *placeholderSrc = self.placeholdSrc;
    
    if ([WXUtility isBlankString:placeholderSrc]) {
        return;
    }
    
    WXLogDebug(@"Updating image, component:%@, placeholder:%@ ", self.ref, placeholderSrc);
    NSString *newURL = [self.placeholdSrc copy];
    WX_REWRITE_URL(self.placeholdSrc, 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;
            UIImage *viewImage = ((UIImageView *)strongSelf.view).image;
            if (error) {
                downloadFailedBlock(placeholderSrc,error);
                if ([strongSelf isViewLoaded] && !viewImage) {
                    ((UIImageView *)(strongSelf.view)).image = nil;
                    [strongSelf readyToRender];
                }
                return;
            }
            if (![placeholderSrc isEqualToString:strongSelf.placeholdSrc]) {
                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 *imageSrc = [NSString stringWithFormat:@"%@", self.imageSrc?:@""];
    if ([WXUtility isBlankString:imageSrc]) {
        WXLogError(@"image src is empty");
        return;
    }
    
    WXLogDebug(@"Updating image:%@, component:%@", self.imageSrc, self.ref);
    NSDictionary *userInfo = @{@"imageQuality":@(self.imageQuality), @"imageSharp":@(self.imageSharp), @"blurRadius":@(self.blurRadius), @"instanceId":[self _safeInstanceId], @"pageURL": self.weexInstance.scriptURL ?: @""};
    NSString * newURL = [imageSrc copy];
    WX_REWRITE_URL(imageSrc, 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.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(imageSrc, error);
                [strongSelf readyToRender];
                return ;
            }
            
            if (![imageSrc isEqualToString:strongSelf.imageSrc]) {
                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
