/*
 * 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 "WXComponentManager.h"
#import "WXComponent.h"
#import "WXComponent_internal.h"
#import "WXComponent+DataBinding.h"
#import "WXComponentFactory.h"
#import "WXDefine.h"
#import "NSArray+Weex.h"
#import "WXSDKInstance.h"
#import "WXAssert.h"
#import "WXUtility.h"
#import "WXMonitor.h"
#import "WXScrollerProtocol.h"
#import "WXSDKManager.h"
#import "WXSDKError.h"
#import "WXInvocationConfig.h"
#import "WXHandlerFactory.h"
#import "WXValidateProtocol.h"
#import "WXPrerenderManager.h"
#import "WXSDKInstance_performance.h"
#import "WXRootView.h"
#import "WXComponent+Layout.h"
#import "WXCoreBridge.h"
#import "WXComponent_performance.h"
#import "WXAnalyzerCenter.h"
#import "WXDisplayLinkManager.h"
#import "WXDarkSchemeProtocol.h"
#import "WXSDKInstance_private.h"

static NSThread *WXComponentThread;

/* Task scheduled on component thread and triggered every N display link ticks.
 If display link is stopped, the tasks are also suspended. */
@interface WXComponentThreadTickTask : NSObject

@property (nonatomic, assign) NSUInteger displayTickCount; // Triggered every N display link ticks
@property (nonatomic, copy) dispatch_block_t block;

@end

@implementation WXComponentThreadTickTask

+ (instancetype)taskWithBlock:(dispatch_block_t)block tickCount:(NSUInteger)tickCount
{
    WXComponentThreadTickTask* task = [[WXComponentThreadTickTask alloc] init];
    task.displayTickCount = tickCount;
    task.block = block;
    return task;
}

@end

#define WXAssertComponentExist(component)  WXAssert(component, @"component not exists")
#define MAX_DROP_FRAME_FOR_BATCH   200

@interface WXComponentManager () <WXDisplayLinkClient>
@end

@implementation WXComponentManager
{
    __weak WXSDKInstance *_weexInstance;
    BOOL _isValid;
    
    BOOL _stopRunning;
    NSUInteger _noTaskTickCount;
    
    // access only on component thread
    NSMapTable<NSString *, WXComponent *> *_indexDict;
    NSMutableArray<dispatch_block_t> *_uiTaskQueue;
    NSMutableDictionary *_uiPrerenderTaskQueue;
    
    NSUInteger _displayTick;
    NSMutableArray<WXComponentThreadTickTask*> *_displayTaskQueue;
    
    // vdom depth and component count statistics
    NSUInteger _maxVdomDepth;
    NSUInteger _maxVdomDepthReported;
    NSUInteger _maxComponentCount;
    NSUInteger _maxComponentCountReported;

    WXComponent *_rootComponent;
    NSMutableArray *_fixedComponents;

    pthread_mutex_t _propertyMutex;
    pthread_mutexattr_t _propertMutexAttr;
    NSUInteger _syncUITaskCount;
}

+ (instancetype)sharedManager
{
    static id _sharedInstance = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        _sharedInstance = [[self alloc] init];
    });
    return _sharedInstance;
}

- (instancetype)initWithWeexInstance:(id)weexInstance
{
    if (self = [self init]) {
        _weexInstance = weexInstance;
        _syncUITaskCount = 0;
        _indexDict = [NSMapTable strongToWeakObjectsMapTable];
        _fixedComponents = [NSMutableArray wx_mutableArrayUsingWeakReferences];
        _uiTaskQueue = [NSMutableArray array];
        _displayTaskQueue = [NSMutableArray array];
        _isValid = YES;
        pthread_mutexattr_init(&_propertMutexAttr);
        pthread_mutexattr_settype(&_propertMutexAttr, PTHREAD_MUTEX_RECURSIVE);
        pthread_mutex_init(&_propertyMutex, &_propertMutexAttr);
        
        WXPerformBlockOnComponentThread(^{
            // We should ensure that [WXDisplayLinkManager sharedInstance] is only invoked in component thread.
            [self _addVdomAndComponentCountTask];
            [self _startDisplayLink];
        });
    }
    
    return self;
}

- (instancetype)init
{
    if (self == [super init]) {
        _suspend = NO;
    }
    return self;
}

- (void)dealloc
{
    [NSMutableArray wx_releaseArray:_fixedComponents];
    pthread_mutex_destroy(&_propertyMutex);
    pthread_mutexattr_destroy(&_propertMutexAttr);
}

#pragma mark Thread Management

+ (NSThread *)componentThread
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        WXComponentThread = [[NSThread alloc] initWithTarget:[self sharedManager] selector:@selector(_runLoopThread) object:nil];
        [WXComponentThread setName:WX_COMPONENT_THREAD_NAME];
        [WXComponentThread setQualityOfService:[[NSThread mainThread] qualityOfService]];
        [WXComponentThread start];
    });
    
    return WXComponentThread;
}

- (void)_runLoopThread
{
    [[NSRunLoop currentRunLoop] addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
    
    while (!_stopRunning) {
        @autoreleasepool {
            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
        }
    }
}

+ (void)_performBlockOnComponentThread:(void (^)(void))block
{
    if([NSThread currentThread] == [self componentThread]){
        block();
    } else {
        [self performSelector:@selector(_performBlockOnComponentThread:)
                     onThread:WXComponentThread
                   withObject:[block copy]
                waitUntilDone:NO];
    }
}

+ (void)_performBlockSyncOnComponentThread:(void (^)(void))block
{
    if([NSThread currentThread] == [self componentThread]){
        block();
    } else {
        [self performSelector:@selector(_performBlockOnComponentThread:)
                     onThread:WXComponentThread
                   withObject:[block copy]
                waitUntilDone:YES];
    }
}

- (void)startComponentTasks
{
    [self _awakeDisplayLink];
}

- (void)rootViewFrameDidChange:(CGRect)frame
{
    WXAssertComponentThread();
    CGSize size = _weexInstance.frame.size;
    [WXCoreBridge setDefaultDimensionIntoRoot:_weexInstance.instanceId
                                        width:size.width height:size.height
                           isWidthWrapContent:size.width == 0.0f isHeightWrapContent:size.height == 0.0f];
    [_rootComponent setNeedsLayout];
    [self startComponentTasks];
}

- (void)_addUITask:(void (^)(void))block
{
    if(!_uiPrerenderTaskQueue){
        _uiPrerenderTaskQueue = [NSMutableDictionary new];
    }
    if(self.weexInstance.needPrerender){
        NSMutableArray<dispatch_block_t> *tasks  = [_uiPrerenderTaskQueue objectForKey:[WXPrerenderManager getTaskKeyFromUrl:self.weexInstance.scriptURL.absoluteString]];
        if(!tasks){
            tasks = [NSMutableArray new];
        }
        [tasks addObject:block];
        [_uiPrerenderTaskQueue setObject:tasks forKey:[WXPrerenderManager getTaskKeyFromUrl:self.weexInstance.scriptURL.absoluteString]];
    }else{
        [_uiTaskQueue addObject:block];
    }
}

- (void)executePrerenderUITask:(NSString *)url
{
    NSMutableArray *tasks  = [_uiPrerenderTaskQueue objectForKey:[WXPrerenderManager getTaskKeyFromUrl:self.weexInstance.scriptURL.absoluteString]];
    for (id block in tasks) {
        [_uiTaskQueue addObject:block];
    }
    tasks = [NSMutableArray new];
    [_uiPrerenderTaskQueue setObject:tasks forKey:[WXPrerenderManager getTaskKeyFromUrl:self.weexInstance.scriptURL.absoluteString]];
}

#pragma mark Component Tree Building

- (void)createBody:(NSString*)ref
              type:(NSString*)type
            styles:(NSDictionary*)styles
        attributes:(NSDictionary*)attributes
            events:(NSArray*)events
      renderObject:(void*)renderObject
{
    WXAssertComponentThread();
    WXAssertParam(ref);
    WXAssertParam(type);
    WXAssertParam(renderObject);
    WXAssert(_rootComponent == nil, @"Create body is invoked twice.");
    
    _rootComponent = [self _buildComponent:ref type:type supercomponent:nil styles:styles attributes:attributes events:events renderObject:renderObject];
    
    if ([WXUtility isDarkSchemeSupportEnabled]) {
        if (attributes[@"invertForDarkScheme"] == nil) {
            WXAutoInvertingBehavior invertingBehavior = _weexInstance.autoInvertingBehavior;
            if (invertingBehavior == WXAutoInvertingBehaviorDefault) {
                _rootComponent.invertForDarkScheme = [[WXSDKInstance darkSchemeColorHandler] defaultInvertValueForRootComponent];
            }
            else if (invertingBehavior == WXAutoInvertingBehaviorAlways) {
                _rootComponent.invertForDarkScheme = YES;
            }
            else {
                _rootComponent.invertForDarkScheme = NO;
            }
        }
    }
    
    CGSize size = _weexInstance.frame.size;
    [WXCoreBridge setDefaultDimensionIntoRoot:_weexInstance.instanceId
                                        width:size.width height:size.height
                           isWidthWrapContent:size.width == 0.0f isHeightWrapContent:size.height == 0.0f];
    
    __weak typeof(self) weakSelf = self;
    WX_MONITOR_INSTANCE_PERF_END(WXFirstScreenJSFExecuteTime, self.weexInstance);
    [self _addUITask:^{
        __strong typeof(self) strongSelf = weakSelf;
        if (strongSelf == nil) {
            return;
        }
        
        strongSelf.weexInstance.rootView.wx_component = strongSelf->_rootComponent;
        [strongSelf.weexInstance.rootView addSubview:strongSelf->_rootComponent.view];
    }];
}

- (void)addComponent:(NSString*)ref
                type:(NSString*)type
           parentRef:(NSString*)parentRef
              styles:(NSDictionary*)styles
          attributes:(NSDictionary*)attributes
              events:(NSArray*)events
               index:(NSInteger)index
        renderObject:(void*)renderObject
{
    WXAssertComponentThread();
    WXAssertParam(ref);
    WXAssertParam(type);
    WXAssertParam(parentRef);
    WXAssertParam(renderObject);
    
    WXComponent *supercomponent = [_indexDict objectForKey:parentRef];
    WXAssertComponentExist(supercomponent);
    
    if (!supercomponent) {
        WXLogWarning(@"addComponent,superRef from js never exit ! check JS action, supRef:%@", parentRef);
        return;
    }
    if([WXAnalyzerCenter isInteractionLogOpen]){
         WXLogDebug(@"wxInteractionAnalyzer: [client][addElementStart]%@,%@,%@",supercomponent.weexInstance.instanceId,type,ref);
    }
    
    supercomponent.weexInstance.apmInstance.hasAddView = YES;
    
    WXComponent *component = [self _buildComponent:ref type:type supercomponent:supercomponent styles:styles attributes:attributes events:events renderObject:renderObject];
    if (!supercomponent.subcomponents) {
        index = 0;
    } else {
        index = (index == -1 ? supercomponent->_subcomponents.count : index);
    }
    if (supercomponent.ignoreInteraction) {
        component.ignoreInteraction = YES;
    } else {
        if ([attributes objectForKey:@"ignoreInteraction"]) {
            component.ignoreInteraction = [[attributes objectForKey:@"ignoreInteraction"] boolValue];
        } else {
            if (component->_positionType == WXPositionTypeFixed) {
                component.ignoreInteraction = YES;
            } else {
                component.ignoreInteraction = NO;
            }
        }
    }
    
    // Not explicitly declare "invertForDarkScheme", inherit
    if (attributes[@"invertForDarkScheme"] == nil) {
        component.invertForDarkScheme = supercomponent.invertForDarkScheme;
    }
    
#ifdef DEBUG
    WXLogDebug(@"flexLayout -> _recursivelyAddComponent : super:(%@,%@):[%f,%f] ,child:(%@,%@):[%f,%f],childClass:%@",
               supercomponent.type,
               supercomponent.ref,
               supercomponent.flexCssNode->getStyleWidth(),
               supercomponent.flexCssNode->getStyleHeight(),
               component.type,
               component.ref,
               component.flexCssNode->getStyleWidth(),
               component.flexCssNode->getStyleHeight(),
               NSStringFromClass([component class])
               );
#endif //DEBUG
    
    BOOL inserted = [supercomponent _insertSubcomponent:component atIndex:index];
    if (!inserted) {
        // component is not inserted, ignore
        [component _setRenderObject:nullptr]; // unbind with RenderObject
        return;
    }
    
    // use _lazyCreateView to forbid component like cell's view creating
    if (supercomponent && component && supercomponent->_lazyCreateView) {
        component->_lazyCreateView = YES;
    }
    
    // update max vdom depth & component count, and will update apm data on next display task.
    [self recordMaximumVirtualDom:component];
    if ([_indexDict count] > _maxComponentCount) {
        _maxComponentCount = [_indexDict count];
    }
    
    if (!component->_isTemplate) {
        __weak typeof(self) weakSelf = self;
        [self _addUITask:^{
            __strong typeof(self) strongSelf = weakSelf;
            if (strongSelf == nil) {
                return;
            }
            
            [supercomponent insertSubview:component atIndex:index];
        }];
    }
    if([WXAnalyzerCenter isInteractionLogOpen]){
        WXLogDebug(@"wxInteractionAnalyzer: [client][addElementEnd]%@,%@,%@",supercomponent.weexInstance.instanceId,type,ref);
    }
}

- (void)moveComponent:(NSString *)ref toSuper:(NSString *)superRef atIndex:(NSInteger)index
{
    WXAssertComponentThread();
    WXAssertParam(ref);
    WXAssertParam(superRef);
    
    WXComponent *component = [_indexDict objectForKey:ref];
    WXComponent *newSupercomponent = [_indexDict objectForKey:superRef];
    WXAssertComponentExist(component);
    WXAssertComponentExist(newSupercomponent);
    
    [component _moveToSupercomponent:newSupercomponent atIndex:index];
    __weak typeof(self) weakSelf = self;
    [self _addUITask:^{
        __strong typeof(self) strongSelf = weakSelf;
        if (strongSelf == nil) {
            return;
        }
        
        [component moveToSuperview:newSupercomponent atIndex:index];
    }];
}

- (void)removeComponent:(NSString *)ref
{
    WXAssertComponentThread();
    WXAssertParam(ref);
    
    WXComponent *component = [_indexDict objectForKey:ref];
    WXAssertComponentExist(component);
    
    if (!component) {
        WXLogWarning(@"removeComponent ref from js never exit ! check JS action, ref :%@",ref);
        return;
    }
    
    [component _setRenderObject:nullptr]; // unbind with RenderObject
    [component _removeFromSupercomponent];
    
    [_indexDict removeObjectForKey:ref];
    
    // remove subcomponents of component from _indexDict and unbind them
    NSMutableArray* subcomponents = [[NSMutableArray alloc] init];
    [component _collectSubcomponents:subcomponents];
    for (WXComponent* c in subcomponents) {
        [c _setRenderObject:nullptr];
        [_indexDict removeObjectForKey:c.ref];
    }
    
    __weak typeof(self) weakSelf = self;
    [self _addUITask:^{
        __strong typeof(self) strongSelf = weakSelf;
        if (strongSelf == nil) {
            return;
        }
        
        if (component.supercomponent) {
            [component.supercomponent willRemoveSubview:component];
        }
        [component removeFromSuperview];
    }];
    
    [self _checkFixedSubcomponentToRemove:component];
}

- (void)appendTreeCreateFinish:(NSString*)ref
{
    WXAssertComponentThread();
    
    // If appending tree，force layout in case of too much tasks piling up in syncQueue
    [self _layoutAndSyncUI];
}

- (void)recordMaximumVirtualDom:(WXComponent*) component
{
    WXAssertComponentExist(component);
    if(!component){
        return;
    }
    int maxDeep =0;
    while (component) {
        maxDeep++;
        component = component.supercomponent;
    }
    
    if (maxDeep > [self weexInstance].performance.maxVdomDeep) {
        [self weexInstance].performance.maxVdomDeep = maxDeep;
    }
    
    if (maxDeep > _maxVdomDepth) {
        _maxVdomDepth = maxDeep;
    }
}

- (void)_checkFixedSubcomponentToRemove:(WXComponent *)component
{
    for (WXComponent *subcomponent in component.subcomponents) {
        if (subcomponent->_positionType == WXPositionTypeFixed) {
             [self _addUITask:^{
                 [subcomponent removeFromSuperview];
             }];
        }
        
        [self _checkFixedSubcomponentToRemove:subcomponent];
    }
}

- (WXComponent *)componentForRef:(NSString *)ref
{
    WXAssertComponentThread();
    
    return [_indexDict objectForKey:ref];
}

- (WXComponent *)componentForRoot
{
    return _rootComponent;
}

- (NSUInteger)numberOfComponents
{
    WXAssertComponentThread();
    
    return _indexDict.count;
}

- (WXComponent *)_buildComponent:(NSString *)ref
                            type:(NSString*)type
                  supercomponent:(WXComponent *)supercomponent
                          styles:(NSDictionary*)styles
                      attributes:(NSDictionary*)attributes
                          events:(NSArray*)events
                    renderObject:(void*)renderObject
{
    double buildStartTime = CACurrentMediaTime()*1000;
    
    if (self.weexInstance.needValidate) {
        id<WXValidateProtocol> validateHandler = [WXHandlerFactory handlerForProtocol:@protocol(WXValidateProtocol)];
        if (validateHandler) {
            WXComponentValidateResult* validateResult;
            if ([validateHandler respondsToSelector:@selector(validateWithWXSDKInstance:component:supercomponent:)]) {
                validateResult = [validateHandler validateWithWXSDKInstance:self.weexInstance component:type supercomponent:supercomponent];
            }
            if (validateResult==nil || !validateResult.isSuccess) {
                type = validateResult.replacedComponent? validateResult.replacedComponent : @"div";
                WXLogError(@"%@",[validateResult.error.userInfo objectForKey:@"errorMsg"]);
            }
        }
    }
    
    WXComponentConfig *config = [WXComponentFactory configWithComponentName:type];
    BOOL isTemplate = [config.properties[@"isTemplate"] boolValue] || (supercomponent && supercomponent->_isTemplate);
    NSDictionary *bindingStyles = nil;
    NSDictionary *bindingAttibutes = nil;
    NSDictionary *bindingEvents = nil;
    NSDictionary *bindingProps = nil;
    if (isTemplate) {
        bindingProps = [self _extractBindingProps:&attributes];
        bindingStyles = [self _extractBindings:&styles];
        bindingAttibutes = [self _extractBindings:&attributes];
        bindingEvents = [self _extractBindingEvents:&events];
    }
    
    Class clazz = NSClassFromString(config.clazz);
    WXComponent *component = [[clazz alloc] init];
    if (component) {
        if (renderObject) {
            [component _setRenderObject:renderObject];
        }
        component = [component initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:self.weexInstance];
        if (isTemplate) {
            component->_isTemplate = YES;
            [component _storeBindingsWithProps:bindingProps styles:bindingStyles attributes:bindingAttibutes events:bindingEvents];
        }
    }
    
    WXAssert(component, @"Component build failed for ref:%@, type:%@", ref, type);
    
    [_indexDict setObject:component forKey:component.ref];
    [component readyToRender];// notify redyToRender event when init
    
    double diffTime = CACurrentMediaTime()*1000 - buildStartTime;
    [self.weexInstance.performance recordComponentCreatePerformance:diffTime forComponent:component];
    
    return component;
}

- (void)addComponent:(WXComponent *)component toIndexDictForRef:(NSString *)ref
{
    [_indexDict setObject:component forKey:ref];
}

- (void)removeComponentForRef:(NSString *)ref
{
    [_indexDict removeObjectForKey:ref];
}

- (NSDictionary *)_extractBindings:(NSDictionary **)attributesOrStylesPoint
{
    NSDictionary *attributesOrStyles = *attributesOrStylesPoint;
    if (!attributesOrStyles) {
        return nil;
    }
    
    NSMutableDictionary *newAttributesOrStyles = [attributesOrStyles mutableCopy];
    NSMutableDictionary *bindingAttributesOrStyles = [NSMutableDictionary dictionary];
    
    [attributesOrStyles enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull attributeOrStyleName, id  _Nonnull attributeOrStyle, BOOL * _Nonnull stop) {
        if ([WXBindingMatchIdentify isEqualToString:attributeOrStyleName] // match
            ||  [WXBindingRepeatIdentify isEqualToString:attributeOrStyleName] // repeat
            ||  [WXBindingOnceIdentify isEqualToString:attributeOrStyleName] // once
            ||([attributeOrStyle isKindOfClass:[NSDictionary class]] && attributeOrStyle[WXBindingIdentify])) {  // {"attributeOrStyleName": {"@binding":"bindingExpression"}
            bindingAttributesOrStyles[attributeOrStyleName] = attributeOrStyle;
            [newAttributesOrStyles removeObjectForKey:attributeOrStyleName];
        } else if ([attributeOrStyle isKindOfClass:[NSArray class]]) {
            // {"attributeOrStyleName":[..., "string", {"@binding":"bindingExpression"}, "string", {"@binding":"bindingExpression"}, ...]
            __block BOOL isBinding = NO;
            [attributeOrStyle enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                if ([obj isKindOfClass:[NSDictionary class]] && obj[WXBindingIdentify]) {
                    isBinding = YES;
                    *stop = YES;
                }
            }];
            
            if (isBinding) {
                bindingAttributesOrStyles[attributeOrStyleName] = attributeOrStyle;
                [newAttributesOrStyles removeObjectForKey:attributeOrStyleName];
            }
        }
    }];
    
    *attributesOrStylesPoint = newAttributesOrStyles;
    
    return bindingAttributesOrStyles;
}

- (NSDictionary *)_extractBindingEvents:(NSArray **)eventsPoint
{
    NSArray *events = *eventsPoint;
    if (events == nil) {
        return nil;
    }
    NSMutableArray *newEvents = [events mutableCopy];
    NSMutableDictionary *bindingEvents = [NSMutableDictionary dictionary];
    [events enumerateObjectsUsingBlock:^(id  _Nonnull event, NSUInteger idx, BOOL * _Nonnull stop) {
        if ([event isKindOfClass:[NSDictionary class]] && event[@"type"] && event[@"params"]) {
            NSString *eventName = event[@"type"];
            NSString *bindingParams = event[@"params"];
            bindingEvents[eventName] = bindingParams;
            newEvents[idx] = eventName;
        }
    }];
    
    *eventsPoint = newEvents;
    return bindingEvents;
}

- (NSDictionary *)_extractBindingProps:(NSDictionary **)attributesPoint
{
    NSDictionary *attributes = *attributesPoint;
    if (attributes == nil) {
        return nil;
    }
    if (attributes[@"@componentProps"]) {
        NSMutableDictionary *newAttributes = [attributes mutableCopy];
        [newAttributes removeObjectForKey:@"@componentProps"];
        *attributesPoint = newAttributes;
        return attributes[@"@componentProps"];
    }
    
    return nil;
}

#pragma mark Reset

- (BOOL)isShouldReset:(id )value
{
    if([value isKindOfClass:[NSString class]]) {
        if(!value || [@"" isEqualToString:value]) {
            return YES;
        }
    }
    return NO;
}

- (void)filterStyles:(NSDictionary *)styles normalStyles:(NSMutableDictionary *)normalStyles resetStyles:(NSMutableArray *)resetStyles
{
    for (NSString *key in styles) {
        id value = [styles objectForKey:key];
        if([self isShouldReset:value]) {
            [resetStyles addObject:key];
        }else{
            [normalStyles setObject:styles[key] forKey:key];
        }
    }
}

- (void)updateStyles:(NSDictionary *)styles forComponent:(NSString *)ref
{
    [self handleStyles:styles forComponent:ref isUpdateStyles:YES];
}

- (void)updatePseudoClassStyles:(NSDictionary *)styles forComponent:(NSString *)ref
{
    [self handleStyles:styles forComponent:ref isUpdateStyles:NO];
}

- (void)handleStyleOnMainThread:(NSDictionary*)styles forComponent:(WXComponent *)component isUpdateStyles:(BOOL)isUpdateStyles
{
    WXAssertParam(styles);
    WXAssertParam(component);
    WXAssertMainThread();
    
    NSMutableDictionary *normalStyles = [NSMutableDictionary new];
    NSMutableArray *resetStyles = [NSMutableArray new];
    [self filterStyles:styles normalStyles:normalStyles resetStyles:resetStyles];
    [component _updateStylesOnMainThread:normalStyles resetStyles:resetStyles];
    [component readyToRender];
    
    NSDictionary* dupStyles = [NSDictionary dictionaryWithDictionary:normalStyles];
    WXPerformBlockOnComponentThread(^{
        [component _updateStylesOnComponentThread:dupStyles resetStyles:resetStyles isUpdateStyles:isUpdateStyles];
    });
}

- (void)handleStyles:(NSDictionary *)styles forComponent:(NSString *)ref isUpdateStyles:(BOOL)isUpdateStyles
{
    WXAssertParam(styles);
    WXAssertParam(ref);
    
    WXComponent *component = [_indexDict objectForKey:ref];
    WXAssertComponentExist(component);
    
    NSMutableDictionary *normalStyles = [NSMutableDictionary new];
    NSMutableArray *resetStyles = [NSMutableArray new];
    [self filterStyles:styles normalStyles:normalStyles resetStyles:resetStyles];
    [component _updateStylesOnComponentThread:normalStyles resetStyles:resetStyles isUpdateStyles:isUpdateStyles];
    
    NSDictionary* dupStyles = [NSDictionary dictionaryWithDictionary:normalStyles];
    [self _addUITask:^{
        [component _updateStylesOnMainThread:dupStyles resetStyles:resetStyles];
        [component readyToRender];
    }];
}

- (void)updateAttributes:(NSDictionary *)attributes forComponent:(NSString *)ref
{
    WXAssertParam(attributes);
    WXAssertParam(ref);
    
    WXComponent *component = [_indexDict objectForKey:ref];
    [component _updateAttributesOnComponentThread:attributes];
    __weak typeof(self) weakSelf = self;
    [self _addUITask:^{
        __strong typeof(self) strongSelf = weakSelf;
        if (strongSelf == nil) {
            return;
        }
        
        [component _updateAttributesOnMainThread:attributes];
        [component readyToRender];
    }];
}

- (BOOL)isTransitionNoneOfComponent:(NSString*)ref
{
    WXAssertComponentThread();
    
    WXComponent *component = [_indexDict objectForKey:ref];
    WXAssertComponentExist(component);
    
    return [component _isTransitionNone];
}

- (BOOL)hasTransitionPropertyInStyles:(NSDictionary*)styles forComponent:(NSString*)ref
{
    WXAssertComponentThread();
    
    WXComponent *component = [_indexDict objectForKey:ref];
    WXAssertComponentExist(component);
    
    return [component _hasTransitionPropertyInStyles:styles];
}

- (void)layoutComponent:(WXComponent*)component frame:(CGRect)frame isRTL:(BOOL)isRTL innerMainSize:(CGFloat)innerMainSize
{
    WXAssertComponentThread();
    WXAssertParam(component);
    
    [component _setIsLayoutRTL:isRTL];
    if (component == _rootComponent) {
        // Synchronize view frame with root component, especially for content wrap mode.
        WXPerformBlockOnMainThread(^{
            if (!self.weexInstance.isRootViewFrozen &&
                (!CGSizeEqualToSize(frame.size, self.weexInstance.frame.size) || !CGSizeEqualToSize(frame.size, self.weexInstance.rootView.frame.size))) {
                CGRect rect = self.weexInstance.rootView.frame; // no change of origin
                rect.size = frame.size;
                self.weexInstance.rootView.frame = rect;
            }
        });
    }
    
    if ([component _isCalculatedFrameChanged:frame]) {
        [component _assignCalculatedFrame:frame];
        [component _assignInnerContentMainSize:innerMainSize];
        [component _frameDidCalculated:YES];
        
        [self _addUITask:^{
            [component _layoutDidFinish];
        }];
    }
    else {
        CGFloat oldValue = [component _getInnerContentMainSize];
        if (oldValue >= 0 && oldValue != innerMainSize) {
            [component _assignCalculatedFrame:frame];
            [component _assignInnerContentMainSize:innerMainSize];
            [component _frameDidCalculated:YES];
            
            [self _addUITask:^{
                [component _layoutDidFinish];
            }];
        }
        else {
            [component _frameDidCalculated:NO];
        }
    }
}

- (void)layoutComponent:(WXComponent*)component
{
    WXAssertComponentThread();
    WXAssertParam(component);
    [component _layoutPlatform];
}

- (void)addEvent:(NSString *)event toComponent:(NSString *)ref
{
    WXAssertComponentThread();
    WXAssertParam(event);
    WXAssertParam(ref);
    
    WXComponent *component = [_indexDict objectForKey:ref];
    WXAssertComponentExist(component);
    
    [component _addEventOnComponentThread:event];
    
    [self _addUITask:^{
        [component _addEventOnMainThread:event];
    }];
}

- (void)removeEvent:(NSString *)event fromComponent:(NSString *)ref
{
    WXAssertComponentThread();
    WXAssertParam(event);
    WXAssertParam(ref);
    
    WXComponent *component = [_indexDict objectForKey:ref];
    WXAssertComponentExist(component);
    
    [component _removeEventOnComponentThread:event];
    
    [self _addUITask:^{
        [component _removeEventOnMainThread:event];
    }];
}

- (void)scrollToComponent:(NSString *)ref options:(NSDictionary *)options
{
    WXAssertComponentThread();
    WXAssertParam(ref);
    
    WXComponent *toComponent = [_indexDict objectForKey:ref];
    WXAssertComponentExist(toComponent);

    id<WXScrollerProtocol> scrollerComponent = toComponent.ancestorScroller;
    if (!scrollerComponent) {
        return;
    }

    CGFloat offset = [[options objectForKey:@"offset"] floatValue];
    BOOL animated = YES;
    if ([options objectForKey:@"animated"]) {
        animated = [[options objectForKey:@"animated"] boolValue];
    }
    
    [self _addUITask:^{
        [scrollerComponent scrollToComponent:toComponent withOffset:offset animated:animated];
    }];
}

#pragma mark Life Cycle

- (void)createFinish
{
    WXAssertComponentThread();
    
    WXSDKInstance *instance  = self.weexInstance;
    [self _addUITask:^{
        
        WX_MONITOR_INSTANCE_PERF_END(WXPTFirstScreenRender, instance);
        WX_MONITOR_INSTANCE_PERF_END(WXPTAllRender, instance);
        WX_MONITOR_SUCCESS(WXMTJSBridge);
        WX_MONITOR_SUCCESS(WXMTNativeRender);
    }];
    [instance updatePerDicAfterCreateFinish];
}

- (void)updateFinish
{
    WXAssertComponentThread();
    
    WXSDKInstance *instance = self.weexInstance;
    WXComponent *root = [_indexDict objectForKey:WX_SDK_ROOT_REF];
    
    [self _addUITask:^{
        if (instance.updateFinish) {
            instance.updateFinish(root.view);
        }
    }];
}

- (void)refreshFinish
{
    WXAssertComponentThread();
    
    WXSDKInstance *instance = self.weexInstance;
    WXComponent *root = [_indexDict objectForKey:WX_SDK_ROOT_REF];
    
    [self _addUITask:^{
        if (instance.refreshFinish) {
            instance.refreshFinish(root.view);
        }
    }];
}

- (void)renderFinish
{
    WXAssertComponentThread();
    
    WXSDKInstance *instance  = self.weexInstance;
    [self _addUITask:^{
        UIView *rootView = instance.rootView;
        [instance.performance onInstanceRenderSuccess:instance];
        if (instance.wlasmRender) {
            [instance.apmInstance forceSetInteractionTime:[WXUtility getUnixFixTimeMillis]];
        }
        if (instance.renderFinish) {
            instance.renderFinish(rootView);
        }
    }];
}

- (void)renderFailed:(NSError *)error {
    WXAssertComponentThread();

    WXSDKInstance *instance  = self.weexInstance;
    [self _addUITask:^{
        if (instance.onFailed) {
            instance.onFailed(error);
        }
    }];
}

- (void)unload
{
    WXAssertComponentThread();
    [self invalidate];
    [self _stopDisplayLink];
    
    // first, unbind with underneath RenderObjects
    {
        NSEnumerator* enumerator = [_indexDict objectEnumerator];
        WXComponent *component;
        while ((component = [enumerator nextObject])) {
            [component _setRenderObject:nullptr];
        }
    }
    
    // second, unload views and finally release components in UI thread
    {
        __block WXComponent* rootComponent = _rootComponent;
        NSEnumerator *enumerator = [[_indexDict copy] objectEnumerator];
        dispatch_async(dispatch_get_main_queue(), ^{
            WXComponent *component;
            while ((component = [enumerator nextObject])) {
                [component _unloadViewWithReusing:NO];
            }
            rootComponent = nil; // finally release all components
        });
    }
    
    // clear containers
    _rootComponent = nil;
    [_indexDict removeAllObjects];
    [_fixedComponents removeAllObjects];
    [_uiTaskQueue removeAllObjects];
}

- (void)invalidate
{
    _isValid = NO;
}

- (BOOL)isValid
{
    return _isValid;
}

#pragma mark Display link task

- (void)_addVdomAndComponentCountTask
{
    __weak WXComponentManager* wself = self;
    [_displayTaskQueue addObject:[WXComponentThreadTickTask taskWithBlock:^{
        __strong WXComponentManager* sself = wself;
        if (sself) {
            if (sself->_maxComponentCount != sself->_maxComponentCountReported) {
                [sself.weexInstance.apmInstance updateMaxStats:KEY_PAGE_STATS_MAX_COMPONENT_NUM curMaxValue:sself->_maxComponentCount];
                sself->_maxComponentCountReported = sself->_maxComponentCount;
            }
            
            if (sself->_maxVdomDepth != sself->_maxVdomDepthReported) {
                [sself.weexInstance.apmInstance updateMaxStats:KEY_PAGE_STATS_MAX_DEEP_DOM curMaxValue:sself->_maxVdomDepth];
                sself->_maxVdomDepthReported = sself->_maxVdomDepth;
            }
        }
    } tickCount:30 /* triggered about every 500ms */]];
}

- (void)_startDisplayLink
{
    WXAssertComponentThread();
    [[WXDisplayLinkManager sharedInstance] registerDisplayClient:self];
    _displayTick = 0;
}

- (void)_stopDisplayLink
{
    WXAssertComponentThread();
    [[WXDisplayLinkManager sharedInstance] unregisterDisplayClient:self];
}

- (void)_suspendDisplayLink
{
    WXAssertComponentThread();
    _suspend = YES;
    [self _executeDisplayTask:YES]; // on suspend, executes every task once
}

- (void)_awakeDisplayLink
{
    WXAssertComponentThread();
    _suspend = NO;
    _displayTick = 0;
}

- (void)_handleDisplayLink
{
    WXAssertComponentThread();
    
    [self _layoutAndSyncUI];
    
    if (!_suspend) {
        // execute tasks in _displayTaskQueue
        _displayTick ++;
        [self _executeDisplayTask:NO];
    }
}

- (void)_executeDisplayTask:(BOOL)onSuspend
{
    for (WXComponentThreadTickTask* task in _displayTaskQueue) {
        if (onSuspend || (_displayTick % task.displayTickCount == 0)) {
            if (task.block) {
                task.block();
            }
        }
    }
}

- (void)_layoutAndSyncUI
{
    [self _layout];
    if(_uiTaskQueue.count > 0){
        [self _syncUITasks];
        _noTaskTickCount = 0;
    } else {
        // suspend display link when there's no task for 1 second, in order to save CPU time.
        _noTaskTickCount ++;
        if (_noTaskTickCount > 60) {
            [self _suspendDisplayLink];
        }
    }
}

- (void)_layout
{
    [WXCoreBridge layoutPage:_weexInstance.instanceId forced:[_rootComponent needsLayout]];
}

- (void) _printFlexComponentFrame:(WXComponent *)component
{
#ifdef DEBUG
    WXLogDebug(@"node ref:%@, type:%@ , frame:%@",
          component.ref,
          component.type,
          NSStringFromCGRect(component.view.layer.frame)
          );
#endif
    
    for (WXComponent *childComponent in component.subcomponents) {
        [self _printFlexComponentFrame:childComponent];
    }
}

- (void)_syncUITasks
{
    NSInteger mismatchBeginIndex = _uiTaskQueue.count;
    for (NSInteger i = _uiTaskQueue.count - 1;i >= 0;i --) {
        if (_uiTaskQueue[i] == WXPerformUITaskBatchEndBlock) {
            _syncUITaskCount = 0;
            // clear when find the matches for end and begin tag
            break;
        }
        if (_uiTaskQueue[i] == WXPerformUITaskBatchBeginBlock) {
            mismatchBeginIndex = i;
            break;
        }
    }
    
    if (mismatchBeginIndex == _uiTaskQueue.count) {//!OCLint
        // here we get end tag or there are not begin and end directives
    } else {
        _syncUITaskCount ++;
        // we only find begin tag but missing end tag,
        if (_syncUITaskCount > (MAX_DROP_FRAME_FOR_BATCH)) {
            // when the wait times come to MAX_DROP_FRAME_FOR_BATCH, we will pop all the stashed operations for user experience.
            mismatchBeginIndex = _uiTaskQueue.count;
            _syncUITaskCount = 0;
        }
    }
    
    if (mismatchBeginIndex > 0) {
        NSArray<dispatch_block_t> *blocks = [_uiTaskQueue subarrayWithRange:NSMakeRange(0, mismatchBeginIndex)];
        [_uiTaskQueue removeObjectsInRange:NSMakeRange(0, mismatchBeginIndex)];
        if (blocks.count) {
            dispatch_async(dispatch_get_main_queue(), ^{
                for(dispatch_block_t block in blocks) {
                    block();
                }
            });
        }
    }
}

#pragma mark Fixed 

- (void)addFixedComponent:(WXComponent *)fixComponent
{
    pthread_mutex_lock(&_propertyMutex);
    [_fixedComponents addObject:fixComponent];
    pthread_mutex_unlock(&_propertyMutex);
}

- (void)removeFixedComponent:(WXComponent *)fixComponent
{
    pthread_mutex_lock(&_propertyMutex);
    [_fixedComponents removeObject:fixComponent];
    pthread_mutex_unlock(&_propertyMutex);
}

#pragma mark Enumerating

- (void)enumerateComponentsUsingBlock:(void (^)(WXComponent *, BOOL *stop))block
{
    if (block == nil || _rootComponent == nil) {
        return;
    }
    
    NSMutableArray* components = [[NSMutableArray alloc] init];
    [components addObject:_rootComponent];
    
    while ([components count] > 0) {
        BOOL stop = NO;
        
        NSArray* thisLevelComponents = [components copy];
        [components removeAllObjects];
        
        // enumerate thisLevelComponents and add next level components to components
        for (WXComponent* c in thisLevelComponents) {
            block(c, &stop);
            if (stop) {
                break;
            }
            
            for (WXComponent* nextLevelComponent in c->_subcomponents) {
                [components addObject:nextLevelComponent];
            }
        }
        
        if (stop) {
            break;
        }
    }
}

static void (^WXPerformUITaskBatchBeginBlock)(void) = ^ () {
#if DEBUG
    WXLogDebug(@"directive BatchBeginBlock");
#endif
};
static void (^WXPerformUITaskBatchEndBlock)(void) = ^ () {
#if DEBUG
    WXLogDebug(@"directive BatchEndBlock");
#endif
};

- (void)performBatchBegin
{
    [self _addUITask:WXPerformUITaskBatchBeginBlock];
}

- (void)performBatchEnd
{
    [self _addUITask:WXPerformUITaskBatchEndBlock];
}

- (void)handleDisplayLink {
    [self _handleDisplayLink];
}

@synthesize suspend=_suspend;


@end

void WXPerformBlockOnComponentThread(void (^block)(void))
{
    [WXComponentManager _performBlockOnComponentThread:block];
}

void WXPerformBlockSyncOnComponentThread(void (^block)(void))
{
    [WXComponentManager _performBlockSyncOnComponentThread:block];
}
