/*
 * 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 "WXSDKInstance.h"
#import "WXSDKInstance_private.h"
#import "WXSDKManager.h"
#import "WXSDKError.h"
#import "WXMonitor.h"
#import "WXAppMonitorProtocol.h"
#import "WXNetworkProtocol.h"
#import "WXModuleFactory.h"
#import "WXHandlerFactory.h"
#import "WXDebugTool.h"
#import "WXUtility.h"
#import "WXAssert.h"
#import "WXLog.h"
#import "WXView.h"
#import "WXRootView.h"
#import "WXThreadSafeMutableDictionary.h"
#import "WXResourceRequest.h"
#import "WXResourceResponse.h"
#import "WXResourceLoader.h"
#import "WXSDKEngine.h"
#import "WXValidateProtocol.h"
#import "WXConfigCenterProtocol.h"
#import "WXTextComponent.h"
#import "WXConvert.h"
#import "WXPrerenderManager.h"
#import "WXJSExceptionProtocol.h"
#import "WXExceptionUtils.h"
#import "WXMonitor.h"
#import "WXBridgeContext.h"
#import "WXJSCoreBridge.h"
#import "WXSDKInstance_performance.h"
#import "WXPageEventNotifyEvent.h"
#import "WXConvertUtility.h"
#import "WXCoreBridge.h"
#import "WXDataRenderHandler.h"
#import "WXDarkSchemeProtocol.h"
#import "WXDarkSchemeModule.h"

#define WEEX_LITE_URL_SUFFIX           @"wlasm"
#define WEEX_RENDER_TYPE_PLATFORM       @"platform"

NSString *const bundleUrlOptionKey = @"bundleUrl";
NSString *const bundleResponseUrlOptionKey = @"bundleResponseUrl";

NSTimeInterval JSLibInitTime = 0;

static NSString* lastPageInfoLock = @"";
static NSDictionary* lastPageInfo = nil;

typedef enum : NSUInteger {
    WXLoadTypeNormal,
    WXLoadTypeBack,
    WXLoadTypeForward,
    WXLoadTypeReload,
    WXLoadTypeReplace
} WXLoadType;

@implementation WXSDKInstance
{
    NSDictionary *_options;
    id _jsData;
    
    WXResourceLoader *_mainBundleLoader;
    WXComponentManager *_componentManager;
    UIView *_rootView;
    WXThreadSafeMutableDictionary *_moduleEventObservers;
    BOOL _performanceCommit;
    BOOL _debugJS;
    id<WXBridgeProtocol> _instanceJavaScriptContext; // sandbox javaScript context
    BOOL _defaultDataRender;
    NSMutableDictionary *_moduleIntercepts;
}

- (void)dealloc
{
    [_moduleEventObservers removeAllObjects];
    [self removeObservers];
}

- (instancetype)init
{
    return [self initWithRenderType:WEEX_RENDER_TYPE_PLATFORM];
}

- (instancetype)initWithRenderType:(NSString*)renderType
{
    self = [super init];
    if (self) {
        if ([WXUtility isDarkSchemeSupportEnabled]) {
            self.schemeName = [WXUtility isSystemInDarkScheme] ? @"dark" : @"light";
        }
        else {
            self.schemeName = @"light";
        }
        
        // Update scheme value in JS environment.
        if (([WXUtility isEnvironmentUsingDarkScheme] && [self.schemeName isEqualToString:@"light"]) ||
            (![WXUtility isEnvironmentUsingDarkScheme] && [self.schemeName isEqualToString:@"dark"])) {
            [[WXBridgeManager sharedManager] resetEnvironment];
        }
        
        _autoInvertingBehavior = WXAutoInvertingBehaviorDefault;
        _renderType = renderType;
        _appearState = YES;
        
        NSInteger instanceId = 0;
        @synchronized(bundleUrlOptionKey) {
            static NSInteger __instance = 0;
            instanceId = __instance % (1024*1024);
            __instance += 2; // always add by 2 as even number
        }
        
        _instanceId = [NSString stringWithFormat:@"%ld", (long)instanceId];
        
        if (self.isCustomRenderType) {
            // check render type is available
            NSSet* availableRenderTypes = [WXCustomPageBridge getAvailableCustomRenderTypes];
            if ([availableRenderTypes containsObject:_renderType]) {
                // custom render page, we use odd instanceId, and (instanceId + 1) is sure not used by other pages.
                _instanceId = [NSString stringWithFormat:@"%ld", (long)(instanceId + 1)];
                [WXCoreBridge setPageArgument:_instanceId key:@"renderType" value:_renderType];
            }
            else {
                WXLogError(@"Unsupported render type '%@'. Regress to platform target.", _renderType);
                _renderType = WEEX_RENDER_TYPE_PLATFORM;
            }
        }
        
        WXLogInfo(@"Create instance: %@, render type: %@", _instanceId, _renderType);
        
        // TODO self is retained here.
        [WXSDKManager storeInstance:self forID:_instanceId];
        
        _bizType = @"";
        _pageName = @"";
        
        _performanceDict = [WXThreadSafeMutableDictionary new];
        _moduleInstances = [WXThreadSafeMutableDictionary new];
        _styleConfigs = [NSMutableDictionary new];
        _attrConfigs = [NSMutableDictionary new];
        _moduleEventObservers = [WXThreadSafeMutableDictionary new];
        _moduleIntercepts = [NSMutableDictionary new];
        _trackComponent = NO;
        _performanceCommit = NO;
        
        _performance = [[WXPerformance alloc] init];
        _apmInstance = [[WXApmForInstance alloc] init];
        
        _defaultDataRender = NO;
        
        _useBackupJsThread = NO;

        [self addObservers];
    }
    return self;
}

- (BOOL)isCustomRenderType
{
    return ![_renderType isEqualToString:WEEX_RENDER_TYPE_PLATFORM];
}

- (id<WXBridgeProtocol>)instanceJavaScriptContext
{
    _debugJS = [WXDebugTool isDevToolDebug];
    
    Class bridgeClass = _debugJS ? NSClassFromString(@"WXDebugger") : [WXJSCoreBridge class];
    
    if (_instanceJavaScriptContext && [_instanceJavaScriptContext isKindOfClass:bridgeClass]) {
        return _instanceJavaScriptContext;
    }
    
    WXAssertBridgeThread();
    if (_instanceJavaScriptContext) {
        _instanceJavaScriptContext = nil;
    }
    
    // WXDebugger is a singleton actually and should not call its init twice.
    _instanceJavaScriptContext = _debugJS ? [NSClassFromString(@"WXDebugger") alloc] : [[WXJSCoreBridge alloc] initWithoutDefaultContext];
    if (!_debugJS) {
        id<WXBridgeProtocol> jsBridge = [[WXSDKManager bridgeMgr] valueForKeyPath:@"bridgeCtx.jsBridge"];
        if (_useBackupJsThread) {
              jsBridge = [[WXSDKManager bridgeMgr] valueForKeyPath:@"backupBridgeCtx.jsBridge"];
        }
        JSContext* globalContex = jsBridge.javaScriptContext;
        JSContextGroupRef contextGroup = JSContextGetGroup([globalContex JSGlobalContextRef]);
        JSClassDefinition classDefinition = kJSClassDefinitionEmpty;
        classDefinition.attributes = kJSClassAttributeNoAutomaticPrototype;
        JSClassRef globalObjectClass = JSClassCreate(&classDefinition);
        JSGlobalContextRef sandboxGlobalContextRef = JSGlobalContextCreateInGroup(contextGroup, globalObjectClass);
        JSClassRelease(globalObjectClass);
        JSContext * instanceContext = [JSContext contextWithJSGlobalContextRef:sandboxGlobalContextRef];
        JSGlobalContextRelease(sandboxGlobalContextRef);
        [WXBridgeContext mountContextEnvironment:instanceContext];
        [_instanceJavaScriptContext setJSContext:instanceContext];
    }
    
    if ([_instanceJavaScriptContext respondsToSelector:@selector(setWeexInstanceId:)]) {
        [_instanceJavaScriptContext setWeexInstanceId:_instanceId];
    }
    if (!_debugJS) {
        [[NSNotificationCenter defaultCenter] postNotificationName:WX_INSTANCE_JSCONTEXT_CREATE_NOTIFICATION object:_instanceJavaScriptContext.javaScriptContext];
    }
    
    return _instanceJavaScriptContext;
}

- (NSString *)description
{
    // get _rootView.frame in JS thread may cause deaklock.
    return [NSString stringWithFormat:@"<%@: %p; id = %@; rootView = %p; url= %@>", NSStringFromClass([self class]), self, _instanceId, (__bridge void*)_rootView, _scriptURL];
}

- (void)setParentInstance:(WXSDKInstance *)parentInstance
{
    WXLogInfo(@"Embed instance %@ into parent instance %@", _instanceId, parentInstance.instanceId);
    _parentInstance = parentInstance;
}

#pragma mark Public Mehtods

- (UIView *)rootView
{
    return _rootView;
}

- (void)setFrame:(CGRect)frame
{
#ifdef DEBUG
    WXLogDebug(@"flexLayout -> setFrame :%@,instance :%@",NSStringFromCGRect(frame),self);
#endif
    if (!CGRectEqualToRect(frame, _frame)) {
        _frame = frame;
        CGFloat screenHeight =  [[UIScreen mainScreen] bounds].size.height;
        if (screenHeight>0) {
            CGFloat pageRatio = frame.size.height/screenHeight *100;
            self.apmInstance.pageRatio = pageRatio>100?100:pageRatio;
        }
        WXPerformBlockOnMainThread(^{
            if (_rootView) {
                _rootView.frame = frame;
                WXPerformBlockOnComponentThread(^{
                    [self.componentManager rootViewFrameDidChange:frame];
                });
            }
        });
    }
}

- (void)setViewportWidth:(CGFloat)viewportWidth
{
    _viewportWidth = viewportWidth;
    
    // notify weex core
    NSString* pageId = _instanceId;
    WXPerformBlockOnComponentThread(^{
        [WXCoreBridge setViewportWidth:pageId width:viewportWidth];
    });
}

- (void)setPageKeepRawCssStyles
{
    [self setPageArgument:@"reserveCssStyles" value:@"true"];
}

- (void)isKeepingRawCssStyles:(void(^)(BOOL))callback {
    NSString* pageId = _instanceId;
    WXPerformBlockOnComponentThread(^{
        if (callback) {
            callback([WXCoreBridge isKeepingRawCssStyles:pageId]);
        }
    });
}

- (void)setPageArgument:(NSString*)key value:(NSString*)value
{
    NSString* pageId = _instanceId;
    WXPerformBlockOnComponentThread(^{
        [WXCoreBridge setPageArgument:pageId key:key value:value];
    });
}

- (void)setScriptURL:(NSURL *)scriptURL
{
    _scriptURL = scriptURL;
    [WXCoreBridge setPageArgument:_instanceId key:@"url" value:[_scriptURL absoluteString]];
}

- (void)setPageRequiredWidth:(CGFloat)width height:(CGFloat)height
{
    _screenSize = CGSizeMake(width, height);
    
    // notify weex core
    NSString* pageId = _instanceId;
    WXPerformBlockOnComponentThread(^{
        [WXCoreBridge setPageRequired:pageId width:width height:height];
    });
}

- (void)renderWithURL:(NSURL *)url
{
    [self renderWithURL:url options:nil data:nil];
}

- (void)_checkPageName
{
    if (nil == self.pageName || [self.pageName isEqualToString:@""]) {
        self.pageName = [self.scriptURL isFileURL] ? self.scriptURL.path.lastPathComponent: self.scriptURL.absoluteString;
    }
    if (nil == self.pageName || [self.pageName isEqualToString:@""]) {
        self.pageName = NSStringFromClass(self.viewController.class)?:@"unkonwPageCauseUnsetNameAndUrlAndVc";
    }
}

- (void)renderWithURL:(NSURL *)url options:(NSDictionary *)options data:(id)data
{
    if (!url) {
        WXLogError(@"Url must be passed if you use renderWithURL");
        return;
    }
    WXLogInfo(@"pageid: %@ renderWithURL: %@", _instanceId, url.absoluteString);
    
    @synchronized (lastPageInfoLock) {
        lastPageInfo = @{@"pageId": [_instanceId copy], @"url": [url absoluteString] ?: @""};
    }
    
    [WXCoreBridge install];
    if (_useBackupJsThread) {
        [[WXSDKManager bridgeMgr] executeJSTaskQueue];
    }

    self.scriptURL = url;
    [self _checkPageName];
    [self.apmInstance startRecord:self.instanceId];
    self.apmInstance.isStartRender = YES;
    
    self.needValidate = [[WXHandlerFactory handlerForProtocol:@protocol(WXValidateProtocol)] needValidate:url];
    WXResourceRequest *request = [WXResourceRequest requestWithURL:url resourceType:WXResourceTypeMainBundle referrer:@"" cachePolicy:NSURLRequestUseProtocolCachePolicy];
    [self _renderWithRequest:request options:options data:data];

    NSURL* nsURL = [NSURL URLWithString:options[@"DATA_RENDER_JS"]];
    [self _downloadAndExecScript:nsURL];
}

- (void)renderView:(id)source options:(NSDictionary *)options data:(id)data
{
    _options = [options isKindOfClass:[NSDictionary class]] ? options : nil;
    _jsData = data;
    WXLogInfo(@"pageid: %@ renderView pageNmae: %@  options: %@", _instanceId, _pageName, options);
    
    @synchronized (lastPageInfoLock) {
        lastPageInfo = @{@"pageId": [_instanceId copy], @"options": options ? [options description] : @""};
    }

    [WXCoreBridge install];
    if (_useBackupJsThread) {
        [[WXSDKManager bridgeMgr] executeJSTaskQueue];
    }

    self.needValidate = [[WXHandlerFactory handlerForProtocol:@protocol(WXValidateProtocol)] needValidate:self.scriptURL];

    if ([source isKindOfClass:[NSString class]]) {
        WXLogDebug(@"Render source: %@, data:%@", self, [WXUtility JSONString:data]);
        [self _renderWithMainBundleString:source];
    } else if ([source isKindOfClass:[NSData class]]) {
        [self _renderWithData:source];
    }
    NSURL* nsURL = [NSURL URLWithString:options[@"DATA_RENDER_JS"]];
    [self _downloadAndExecScript:nsURL];
}

- (void)_downloadAndExecScript:(NSURL *)url {
    [[WXSDKManager bridgeMgr] DownloadJS:_instanceId url:url completion:^(NSString *script) {
        if (!script) {
            return;
        }
        if (self.dataRender) {
            id<WXDataRenderHandler> dataRenderHandler = [WXHandlerFactory handlerForProtocol:@protocol(WXDataRenderHandler)];
            if (dataRenderHandler) {
                [[WXSDKManager bridgeMgr] createInstanceForJS:_instanceId template:script options:_options data:_jsData];

                NSString* instanceId = self.instanceId;
                WXPerformBlockOnComponentThread(^{
                    [dataRenderHandler DispatchPageLifecycle:instanceId];
                });
            }
            else {
                if (self.componentManager.isValid) {
                    WXSDKErrCode errorCode = WX_KEY_EXCEPTION_DEGRADE_EAGLE_RENDER_ERROR;
                    NSError *error = [NSError errorWithDomain:WX_ERROR_DOMAIN code:errorCode userInfo:@{@"message":@"No data render handler found!"}];
                    WXPerformBlockOnComponentThread(^{
                        [self.componentManager renderFailed:error];
                    });
                }
            }
            return;
        }
    }];
}

- (NSString *) bundleTemplate
{
    return self.mainBundleString;
}

- (void)_renderWithData:(NSData *)contents
{
    if (!self.instanceId) {
        WXLogError(@"Fail to find instance！");
        return;
    }
    
    if (_isRendered) {
        [WXExceptionUtils commitCriticalExceptionRT:self.instanceId errCode:[NSString stringWithFormat:@"%d", WX_ERR_RENDER_TWICE] function:@"_renderWithData:" exception:[NSString stringWithFormat:@"instance is rendered twice"] extParams:nil];
        return;
    }

    //some case , with out render (url)
    [self.apmInstance startRecord:self.instanceId];
    self.apmInstance.isStartRender = YES;
    
    [_apmInstance setProperty:KEY_PAGE_PROPERTIES_UIKIT_TYPE withValue:_renderType?: WEEX_RENDER_TYPE_PLATFORM];
    if (self.dataRender) {
        [self.apmInstance setProperty:KEY_PAGE_PROPERTIES_RENDER_TYPE withValue:@"eagle"];
    }

    self.performance.renderTimeOrigin = CACurrentMediaTime()*1000;
    self.performance.renderUnixTimeOrigin = [WXUtility getUnixFixTimeMillis];
    long renderOriginTimePlatform = [self.apmInstance onStage:KEY_PAGE_STAGES_RENDER_ORGIGIN];
    
    // pass render origin time to page
    [WXCoreBridge setPageArgument:_instanceId key:@"renderTimeOrigin" value:[NSString stringWithFormat:@"%lld", (long long)([[NSDate date] timeIntervalSince1970] * 1000)]];
    [WXCoreBridge setPageArgument:_instanceId key:@"renderTimeOriginPlatform" value:[NSString stringWithFormat:@"%lld", (long long)renderOriginTimePlatform]];

    if (![WXUtility isBlankString:self.pageName]) {
        WXLog(@"Start rendering page:%@", self.pageName);
    } else {
        WXLogWarning(@"WXSDKInstance's pageName should be specified.");
        id<WXJSExceptionProtocol> jsExceptionHandler = [WXHandlerFactory handlerForProtocol:@protocol(WXJSExceptionProtocol)];
        if ([jsExceptionHandler respondsToSelector:@selector(onRuntimeCheckException:)]) {
            WXRuntimeCheckException * runtimeCheckException = [WXRuntimeCheckException new];
            runtimeCheckException.exception = @"We highly recommend you to set pageName.\n Using WXSDKInstance * instance = [WXSDKInstance new]; instance.pageName = @\"your page name\" to fix it";
            [jsExceptionHandler onRuntimeCheckException:runtimeCheckException];
        }
    }

    id<WXPageEventNotifyEventProtocol> pageEvent = [WXSDKEngine handlerForProtocol:@protocol(WXPageEventNotifyEventProtocol)];
    if ([pageEvent respondsToSelector:@selector(pageStart:)]) {
        [pageEvent pageStart:self.instanceId];
    }

    WX_MONITOR_INSTANCE_PERF_START(WXPTFirstScreenRender, self);
    WX_MONITOR_INSTANCE_PERF_START(WXPTAllRender, self);

    NSMutableDictionary *dictionary = [_options mutableCopy];
    if ([WXLog logLevel] >= WXLogLevelLog) {
        dictionary[@"debug"] = @(YES);
    }

    WXPerformBlockOnMainThread(^{
        if (self.isCustomRenderType) {
            self->_rootView = [WXCustomPageBridge createPageRootView:self.instanceId pageType:self.renderType frame:self.frame];
        }
        else {
            self->_rootView = [[WXRootView alloc] initWithFrame:self.frame];
            ((WXRootView*)(self->_rootView)).instance = self;
        }
        
        if (self.onCreate) {
            self.onCreate(self->_rootView);
        }
    });
    // ensure default modules/components/handlers are ready before create instance
    [WXSDKEngine registerDefaults];
    id darkSchemeHandler = [WXSDKInstance darkSchemeColorHandler];
    [[NSNotificationCenter defaultCenter] postNotificationName:WX_SDKINSTANCE_WILL_RENDER object:self];
    if ([WXSDKInstance darkSchemeColorHandler] != darkSchemeHandler) {
        // After notification, handler for WXDarkSchemeProtocol might change.
        self.schemeName = [WXUtility isSystemInDarkScheme] ? @"dark" : @"light";
    }

    if ([self _handleConfigCenter]) {
        int wxErrorCode = 9999;
        NSError * error = [NSError errorWithDomain:WX_ERROR_DOMAIN code:wxErrorCode userInfo:nil];
        if (self.onFailed) {
            self.onFailed(error);
        }
        [self.apmInstance setProperty:KEY_PROPERTIES_ERROR_CODE withValue:[@(wxErrorCode) stringValue]];
        return;
    }

    [[WXSDKManager bridgeMgr] createInstance:self.instanceId contents:contents options:dictionary data:_jsData];

    // WX_MONITOR_PERF_SET(WXPTBundleSize, [data length], self);
    _isRendered = YES;
}

- (void)_renderWithMainBundleString:(NSString *)mainBundleString
{
    if (!self.instanceId) {
        WXLogError(@"Fail to find instance！");
        return;
    }
    
    if (_isRendered) {
        [WXExceptionUtils commitCriticalExceptionRT:self.instanceId errCode:[NSString stringWithFormat:@"%d", WX_ERR_RENDER_TWICE] function:@"_renderWithMainBundleString:" exception:[NSString stringWithFormat:@"instance is rendered twice"] extParams:nil];
        return;
    }

    //some case , with out render (url)
    [self _checkPageName];
    [self.apmInstance startRecord:self.instanceId];
    self.apmInstance.isStartRender = YES;
    
    [_apmInstance setProperty:KEY_PAGE_PROPERTIES_UIKIT_TYPE withValue:_renderType?: WEEX_RENDER_TYPE_PLATFORM];
    if (self.dataRender) {
        [self.apmInstance setProperty:KEY_PAGE_PROPERTIES_RENDER_TYPE withValue:@"eagle"];
    }
    
    self.performance.renderTimeOrigin = CACurrentMediaTime()*1000;
    self.performance.renderUnixTimeOrigin = [WXUtility getUnixFixTimeMillis];
    long renderOriginTimePlatform = [self.apmInstance onStage:KEY_PAGE_STAGES_RENDER_ORGIGIN];
    
    // pass render origin time to page
    [WXCoreBridge setPageArgument:_instanceId key:@"renderTimeOrigin" value:[NSString stringWithFormat:@"%lld", (long long)([[NSDate date] timeIntervalSince1970] * 1000)]];
    [WXCoreBridge setPageArgument:_instanceId key:@"renderTimeOriginPlatform" value:[NSString stringWithFormat:@"%lld", (long long)renderOriginTimePlatform]];
    
    if (![WXUtility isBlankString:self.pageName]) {
        WXLog(@"Start rendering page:%@", self.pageName);
    } else {
        WXLogWarning(@"WXSDKInstance's pageName should be specified.");
        id<WXJSExceptionProtocol> jsExceptionHandler = [WXHandlerFactory handlerForProtocol:@protocol(WXJSExceptionProtocol)];
        if ([jsExceptionHandler respondsToSelector:@selector(onRuntimeCheckException:)]) {
            WXRuntimeCheckException * runtimeCheckException = [WXRuntimeCheckException new];
            runtimeCheckException.exception = @"We highly recommend you to set pageName.\n Using WXSDKInstance * instance = [WXSDKInstance new]; instance.pageName = @\"your page name\" to fix it";
            [jsExceptionHandler onRuntimeCheckException:runtimeCheckException];
        }
    }
    if (!self.userInfo) {
        self.userInfo = [NSMutableDictionary new];
    }
    if (!self.userInfo[@"jsMainBundleStringContentLength"]) {
        self.userInfo[@"jsMainBundleStringContentLength"] = @([mainBundleString length]);
    }
    
    id<WXPageEventNotifyEventProtocol> pageEvent = [WXSDKEngine handlerForProtocol:@protocol(WXPageEventNotifyEventProtocol)];
    if ([pageEvent respondsToSelector:@selector(pageStart:)]) {
        [pageEvent pageStart:self.instanceId];
    }

    WX_MONITOR_INSTANCE_PERF_START(WXPTFirstScreenRender, self);
    WX_MONITOR_INSTANCE_PERF_START(WXPTAllRender, self);
    
    NSMutableDictionary *dictionary = [_options mutableCopy];
    if ([WXLog logLevel] >= WXLogLevelLog) {
        dictionary[@"debug"] = @(YES);
    }
    
    if ([WXDebugTool getReplacedBundleJS]) {
        mainBundleString = [WXDebugTool getReplacedBundleJS];
    }
    
    WXPerformBlockOnMainThread(^{
        if (self.isCustomRenderType) {
            self->_rootView = [WXCustomPageBridge createPageRootView:self.instanceId pageType:self.renderType frame:self.frame];
        }
        else {
            self->_rootView = [[WXRootView alloc] initWithFrame:self.frame];
            ((WXRootView*)(self->_rootView)).instance = self;
        }
        
        if (self.onCreate) {
            self.onCreate(self->_rootView);
        }
    });
    // ensure default modules/components/handlers are ready before create instance
    [WXSDKEngine registerDefaults];
    id darkSchemeHandler = [WXSDKInstance darkSchemeColorHandler];
    [[NSNotificationCenter defaultCenter] postNotificationName:WX_SDKINSTANCE_WILL_RENDER object:self];
    if ([WXSDKInstance darkSchemeColorHandler] != darkSchemeHandler) {
        // After notification, handler for WXDarkSchemeProtocol might change.
        self.schemeName = [WXUtility isSystemInDarkScheme] ? @"dark" : @"light";
    }
    
    _mainBundleString = mainBundleString;
    if ([self _handleConfigCenter]) {
        int wxErrorCode = 9999;
        NSError * error = [NSError errorWithDomain:WX_ERROR_DOMAIN code:wxErrorCode userInfo:nil];
        if (self.onFailed) {
            self.onFailed(error);
        }
        [self.apmInstance setProperty:KEY_PROPERTIES_ERROR_CODE withValue:[@(wxErrorCode) stringValue]];
        return;
    }
    
    [[WXSDKManager bridgeMgr] createInstance:self.instanceId template:mainBundleString options:dictionary data:_jsData];
    
    WX_MONITOR_PERF_SET(WXPTBundleSize, [mainBundleString lengthOfBytesUsingEncoding:NSUTF8StringEncoding], self);
    
    _isRendered = YES;
}

- (BOOL)_handleConfigCenter
{
    id configCenter = [WXSDKEngine handlerForProtocol:@protocol(WXConfigCenterProtocol)];
    if ([configCenter respondsToSelector:@selector(configForKey:defaultValue:isDefault:)]) {		
        BOOL enableRTLLayoutDirection = [[configCenter configForKey:@"iOS_weex_ext_config.enableRTLLayoutDirection" defaultValue:@(YES) isDefault:NULL] boolValue];
        [WXUtility setEnableRTLLayoutDirection:enableRTLLayoutDirection];
        
        BOOL isIOS13 = [[[UIDevice currentDevice] systemVersion] integerValue] == 13;
        BOOL useMRCForInvalidJSONObject = [[configCenter configForKey:@"iOS_weex_ext_config.useMRCForInvalidJSONObject" defaultValue:@(YES) isDefault:NULL] boolValue];
        BOOL alwaysUseMRCForObjectToWeexCore = [[configCenter configForKey:@"iOS_weex_ext_config.alwaysUseMRC" defaultValue:@(NO) isDefault:NULL] boolValue];
        ConvertSwitches(isIOS13, useMRCForInvalidJSONObject, alwaysUseMRCForObjectToWeexCore);
        
        BOOL isDarkSchemeSupportEnabled = [[configCenter configForKey:@"iOS_weex_ext_config.supportDarkScheme" defaultValue:@(YES) isDefault:NULL] boolValue];
        if (@available(iOS 13.0, *)) {
        }
        else {
            isDarkSchemeSupportEnabled = NO;
        }
        [WXUtility setDarkSchemeSupportEnable:isDarkSchemeSupportEnabled];
    }
    else {
        BOOL isIOS13 = [[[UIDevice currentDevice] systemVersion] integerValue] == 13;
        ConvertSwitches(isIOS13, YES, NO);
    }
    return NO;
}

- (void)renderWithMainBundleString:(NSNotification*)notification
{
    [self _renderWithMainBundleString:_mainBundleString];
}

- (void)_renderWithRequest:(WXResourceRequest *)request options:(NSDictionary *)options data:(id)data;
{
    NSURL *url = request.URL;
    self.scriptURL = url;
    _jsData = data;
    if (![options isKindOfClass:[NSDictionary class]]) {
        options = @{};
    }
    NSMutableDictionary *newOptions = [options mutableCopy] ?: [NSMutableDictionary new];
    
    if (!newOptions[bundleUrlOptionKey]) {
        newOptions[bundleUrlOptionKey] = url.absoluteString;
    }

    if ( [url.absoluteString containsString:@"__data_render=true"]) {
        newOptions[@"DATA_RENDER"] = @(YES);
    }

    if ([url.absoluteString hasSuffix:WEEX_LITE_URL_SUFFIX] || [url.absoluteString containsString:@"__eagle=true"]) {
        newOptions[@"WLASM_RENDER"] = @(YES);
    }

    // compatible with some wrong type, remove this hopefully in the future.
    if ([newOptions[bundleUrlOptionKey] isKindOfClass:[NSURL class]]) {
        WXLogWarning(@"Error type in options with key:bundleUrl, should be of type NSString, not NSURL!");
        newOptions[bundleUrlOptionKey] = ((NSURL*)newOptions[bundleUrlOptionKey]).absoluteString;
    }
    _options = [newOptions copy];
    request.userAgent = [WXUtility userAgent];
    
    WX_MONITOR_INSTANCE_PERF_START(WXPTJSDownload, self);
    __weak typeof(self) weakSelf = self;
    _mainBundleLoader = [[WXResourceLoader alloc] initWithRequest:request];;
     [self.apmInstance onStage:KEY_PAGE_STAGES_DOWN_BUNDLE_START];
    _mainBundleLoader.onFinished = ^(WXResourceResponse *response, NSData *data) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        if (strongSelf == nil) {
            return;
        }

        NSMutableDictionary* optionsCopy = [strongSelf->_options mutableCopy];
        optionsCopy[bundleResponseUrlOptionKey] = [response.URL absoluteString];
        strongSelf->_options = [optionsCopy copy];
        
        NSError *error = nil;
        if ([response isKindOfClass:[NSHTTPURLResponse class]] && ((NSHTTPURLResponse *)response).statusCode != 200) {
            error = [NSError errorWithDomain:WX_ERROR_DOMAIN
                                        code:((NSHTTPURLResponse *)response).statusCode
                                    userInfo:@{@"message":@"status code error."}];
            if (strongSelf.onFailed) {
                strongSelf.onFailed(error);
            }
        }
        
        if (strongSelf.onJSDownloadedFinish) {
            strongSelf.onJSDownloadedFinish(response, request, data, error);
        }
        
        if (error) {
            [WXExceptionUtils commitCriticalExceptionRT:strongSelf.instanceId
                                                errCode:[NSString stringWithFormat:@"%d", WX_KEY_EXCEPTION_JS_DOWNLOAD]
                                               function:@"_renderWithRequest:options:data:"
                                              exception:[NSString stringWithFormat:@"download bundle error :%@",[error localizedDescription]]
                                              extParams:nil];
        
            strongSelf.apmInstance.isDownLoadFailed = YES;
            [strongSelf.apmInstance setProperty:KEY_PROPERTIES_ERROR_CODE withValue:[@(WX_KEY_EXCEPTION_JS_DOWNLOAD) stringValue]];
            return;
        }

        if (!data) {
            NSString *errorMessage = [NSString stringWithFormat:@"Request to %@ With no data return", request.URL];
            WX_MONITOR_FAIL_ON_PAGE(WXMTJSDownload, WX_ERR_JSBUNDLE_DOWNLOAD, errorMessage, strongSelf.pageName);
            [WXExceptionUtils commitCriticalExceptionRT:strongSelf.instanceId
                                                errCode:[NSString stringWithFormat:@"%d", WX_KEY_EXCEPTION_JS_DOWNLOAD]
                                               function:@"_renderWithRequest:options:data:"
                                              exception:errorMessage
                                              extParams:nil];
            
            if (strongSelf.onFailed) {
                strongSelf.onFailed(error);
            }
            strongSelf.apmInstance.isDownLoadFailed = YES;
            [strongSelf.apmInstance setProperty:KEY_PROPERTIES_ERROR_CODE withValue:[@(WX_KEY_EXCEPTION_JS_DOWNLOAD) stringValue]];
            return;
        }
        
        if (([newOptions[@"DATA_RENDER"] boolValue] && [newOptions[@"RENDER_WITH_BINARY"] boolValue]) || [newOptions[@"WLASM_RENDER"] boolValue]) {
            [strongSelf.apmInstance onStage:KEY_PAGE_STAGES_DOWN_BUNDLE_END];
            [strongSelf _renderWithData:data];
            return;
        }

        NSString *jsBundleString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        if (!jsBundleString) {
            WX_MONITOR_FAIL_ON_PAGE(WXMTJSDownload, WX_ERR_JSBUNDLE_STRING_CONVERT, @"data converting to string failed.", strongSelf.pageName)
            [strongSelf.apmInstance setProperty:KEY_PROPERTIES_ERROR_CODE withValue:[@(WX_ERR_JSBUNDLE_STRING_CONVERT) stringValue]];
            return;
        }
        if (!strongSelf.userInfo) {
            strongSelf.userInfo = [NSMutableDictionary new];
        }
        
        NSUInteger bundleSize = [jsBundleString length];
        [strongSelf.apmInstance updateDiffStats:KEY_PAGE_STATS_BUNDLE_SIZE withDiffValue:bundleSize];
        
        strongSelf.userInfo[@"jsMainBundleStringContentLength"] = @(bundleSize);
        strongSelf.userInfo[@"jsMainBundleStringContentMd5"] = [WXUtility md5:jsBundleString];

        WX_MONITOR_SUCCESS_ON_PAGE(WXMTJSDownload, strongSelf.pageName);
        WX_MONITOR_INSTANCE_PERF_END(WXPTJSDownload, strongSelf);
        
        if (strongSelf.onRenderTerminateWhenJSDownloadedFinish) {
            if (strongSelf.onRenderTerminateWhenJSDownloadedFinish(response, request, data, error)) {
                return;
            }
        }
        
        [strongSelf.apmInstance onStage:KEY_PAGE_STAGES_DOWN_BUNDLE_END];
        [strongSelf.apmInstance updateExtInfoFromResponseHeader:response.allHeaderFields];
        [strongSelf _renderWithMainBundleString:jsBundleString];
        [WXMonitor performanceFinishWithState:DebugAfterRequest instance:strongSelf];
    };
    
    _mainBundleLoader.onFailed = ^(NSError *loadError) {
        WXLogError(@"Request failed with error: %@", loadError);
        
        NSString *errorMessage = [NSString stringWithFormat:@"Request to %@ occurs an error:%@, info:%@", request.URL, loadError.localizedDescription, loadError.userInfo];
        long wxErrorCode = [loadError.domain isEqualToString:NSURLErrorDomain] && loadError.code == NSURLErrorNotConnectedToInternet ? WX_ERR_NOT_CONNECTED_TO_INTERNET : WX_ERR_JSBUNDLE_DOWNLOAD;

        WX_MONITOR_FAIL_ON_PAGE(WXMTJSDownload, wxErrorCode, errorMessage, weakSelf.pageName);
        
        NSMutableDictionary *allUserInfo = [[NSMutableDictionary alloc] initWithDictionary:error.userInfo];
        [allUserInfo addEntriesFromDictionary:loadError.userInfo];
        NSError *errorWithReportMsg = [NSError errorWithDomain:error.domain
                                             code:error.code
                                         userInfo:allUserInfo];
      
        if (weakSelf.onFailed) {
            weakSelf.onFailed(errorWithReportMsg);
        }
        [weakSelf.apmInstance setProperty:KEY_PROPERTIES_ERROR_CODE withValue:[@(wxErrorCode) stringValue]];
    };
    
    [_mainBundleLoader start];
}

- (void)reload:(BOOL)forcedReload
{
    // TODO: [self unload]
    if (!_scriptURL) {
        WXLogError(@"No script URL found while reloading!");
        return;
    }
    
    NSURLRequestCachePolicy cachePolicy = forcedReload ? NSURLRequestReloadIgnoringCacheData : NSURLRequestUseProtocolCachePolicy;
    WXResourceRequest *request = [WXResourceRequest requestWithURL:_scriptURL resourceType:WXResourceTypeMainBundle referrer:_scriptURL.absoluteString cachePolicy:cachePolicy];
    [self _renderWithRequest:request options:_options data:_jsData];
}

- (void)reloadLayout
{
    NSString* pageId = _instanceId;
    WXPerformBlockOnComponentThread(^{
        [WXCoreBridge reloadPageLayout:pageId];
    });
}

- (void)refreshInstance:(id)data
{
    WXLogDebug(@"refresh instance: %@, data:%@", self, [WXUtility JSONString:data]);
    
    if (!self.instanceId) {
        WXLogError(@"Fail to find instance！");
        return;
    }
    
    [[WXSDKManager bridgeMgr] refreshInstance:self.instanceId data:data];
}

- (void)destroyInstance
{
    WXLogInfo(@"Destroy instance: %@", _instanceId);
    
    [self.apmInstance endRecord];
    NSString *url = @"";
    if ([WXPrerenderManager isTaskExist:[self.scriptURL absoluteString]]) {
        url = [self.scriptURL absoluteString];
    }
    if (!self.instanceId) {
        WXLogError(@"Fail to find instance！");
        return;
    }
    
    id<WXPageEventNotifyEventProtocol> pageEvent = [WXSDKEngine handlerForProtocol:@protocol(WXPageEventNotifyEventProtocol)];
    if ([pageEvent respondsToSelector:@selector(pageDestroy:)]) {
        [pageEvent pageDestroy:self.instanceId];
    }
    [[NSNotificationCenter defaultCenter] postNotificationName:WX_INSTANCE_WILL_DESTROY_NOTIFICATION object:nil userInfo:@{@"instanceId":self.instanceId}];

    [WXPrerenderManager removePrerenderTaskforUrl:[self.scriptURL absoluteString]];
    [WXPrerenderManager destroyTask:self.instanceId];
    BOOL dataRender = self.dataRender;
    BOOL wlasmRender = self.wlasmRender;
    if (!dataRender) {
        [[WXSDKManager bridgeMgr] destroyInstance:self.instanceId];
    }
    
    WXComponentManager* componentManager = self.componentManager;
    NSString* instanceId = self.instanceId;
    
    /* Custom render target, currently we manage the pages by ourselves not by WeexCore.
     We remove the WeexCore page immediately so that any later render commands will be ignored. */
    if ([WXCustomPageBridge isCustomPage:instanceId]) {
        [[WXCustomPageBridge sharedInstance] invalidatePage:instanceId];
    }
    
    WXPerformBlockOnComponentThread(^{
        // Destroy components and views in main thread. Unbind with underneath RenderObjects.
        [componentManager unload];
        
        // Destroy weexcore c++ page and objects.
        [WXCoreBridge closePage:instanceId];
        
        if (dataRender && !wlasmRender) {
            [[WXSDKManager bridgeMgr] destroyInstance:instanceId];
        }

        // Destroy heron render target page
        if ([WXCustomPageBridge isCustomPage:instanceId]) {
            [[WXCustomPageBridge sharedInstance] removePage:instanceId];
        }
        
        // Reading config from orange for Release instance in Main Thread or not, for Bug #15172691 +{
        dispatch_async(dispatch_get_main_queue(), ^{
            [WXSDKManager removeInstanceforID:instanceId];
            WXLogInfo(@"Finally remove instance: %@", instanceId);
        });
        //+}
    });
    
    if (url.length > 0) {
        [WXPrerenderManager addGlobalTask:url callback:nil];
    }
}

- (void)forceGarbageCollection
{
    [[WXSDKManager bridgeMgr] forceGarbageCollection];
}

- (void)updateState:(WXState)state
{
    if (!self.instanceId) {
        WXLogError(@"Fail to find instance！");
        return;
    }
    
    if (!_performanceCommit && state == WeexInstanceDisappear) {
        [self updatePerDicBeforExit];
        WX_MONITOR_INSTANCE_PERF_COMMIT(self);
        _performanceCommit = YES;
    }
    
    NSMutableDictionary *data = [NSMutableDictionary dictionary];
    [data setObject:[NSString stringWithFormat:@"%ld",(long)state] forKey:@"state"];
    //[[WXSDKManager bridgeMgr] updateState:self.instanceId data:data];
    
    // First post internal notification
    [[NSNotificationCenter defaultCenter] postNotificationName:WX_INSTANCE_NOTIFICATION_UPDATE_STATE_INTERNAL object:self userInfo:data];
    [[NSNotificationCenter defaultCenter] postNotificationName:WX_INSTANCE_NOTIFICATION_UPDATE_STATE object:self userInfo:data];
}

- (id)moduleForClass:(Class)moduleClass
{
    if (!moduleClass)
        return nil;
    
    id<WXModuleProtocol> moduleInstance = self.moduleInstances[NSStringFromClass(moduleClass)];
    if (!moduleInstance) {
        moduleInstance = [[moduleClass alloc] init];
        if ([moduleInstance respondsToSelector:@selector(setWeexInstance:)])
            [moduleInstance setWeexInstance:self];
        self.moduleInstances[NSStringFromClass(moduleClass)] = moduleInstance;
    }
    
    return moduleInstance;
}

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

- (NSUInteger)numberOfComponents
{
    WXAssertComponentThread();
    
    return [_componentManager numberOfComponents];
}

- (void)enumerateComponentsUsingBlock:(void (^)(WXComponent *, BOOL *stop))block
{
    WXAssertComponentThread();
    
    [_componentManager enumerateComponentsUsingBlock:block];
}

- (void)fireGlobalEvent:(NSString *)eventName params:(NSDictionary *)params
{
    if (!params){
        params = [NSDictionary dictionary];
    }
    NSDictionary * userInfo = @{
            @"weexInstance":self.instanceId,
            @"param":params
    };
    [[NSNotificationCenter defaultCenter] postNotificationName:eventName object:self userInfo:userInfo];
}

- (void)fireModuleEvent:(Class)module eventName:(NSString *)eventName params:(NSDictionary*)params
{
    NSDictionary * userInfo = @{
                                @"moduleId":NSStringFromClass(module)?:@"",
                                @"param":params?:@{},
                                @"eventName":eventName
                                };
    
    [[NSNotificationCenter defaultCenter] postNotificationName:WX_MODULE_EVENT_FIRE_NOTIFICATION object:self userInfo:userInfo];
}

- (CGFloat)pixelScaleFactor
{
    CGFloat usingScreenWidth = _screenSize.width > 0 ? _screenSize.width : [WXCoreBridge getDeviceSize].width;
    CGFloat usingViewPort = _viewportWidth > 0 ? _viewportWidth : WXDefaultScreenWidth;
    return usingScreenWidth / usingViewPort;
}
    
- (BOOL)wlasmRender {
    if ([_options[@"WLASM_RENDER"] boolValue] || [_scriptURL.pathExtension isEqualToString:@"wlasm"] || [_scriptURL.pathExtension isEqualToString:@"wlm"]) {
        return YES;
    }
    return NO;
}

- (BOOL)dataRender
{
    if ([_options[@"DATA_RENDER"] boolValue] || [_options[@"WLASM_RENDER"] boolValue]) {
        return YES;
    }
    return _defaultDataRender;
}

- (NSURL *)completeURL:(NSString *)url
{
    if (!_scriptURL) {
        return [NSURL URLWithString:url];
    }
    if ([url hasPrefix:@"//"] && [_scriptURL isFileURL]) {
        return [NSURL URLWithString:url];
    }
    if (!url) {
        return nil;
    }
    NSURL *result = [NSURL URLWithString:url relativeToURL:_scriptURL];
    if (result) {
        return result;
    }
    // if result is nil, try url-encode the 'url' string.
    return [NSURL URLWithString:[url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]] relativeToURL:_scriptURL];
}

- (BOOL)checkModuleEventRegistered:(NSString*)event moduleClassName:(NSString*)moduleClassName
{
    NSDictionary * observer = [_moduleEventObservers objectForKey:moduleClassName];
    return observer && observer[event]? YES:NO;
}

#pragma mark Private Methods

- (void)_addModuleEventObserversWithModuleMethod:(WXModuleMethod *)method
{
    if ([method.arguments count] < 2) {
        WXLogError(@"please check your method parameter!!");
        return;
    }
    if(![method.arguments[0] isKindOfClass:[NSString class]]) {
        // arguments[0] will be event name, so it must be a string type value here.
        return;
    }
    NSMutableArray * methodArguments = [method.arguments mutableCopy];
    if ([methodArguments count] == 2) {
        [methodArguments addObject:@{@"once": @false}];
    }
    if (![methodArguments[2] isKindOfClass:[NSDictionary class]]) {
        //arguments[2] is the option value, so it must be a dictionary.
        return;
    }
    Class moduleClass =  [WXModuleFactory classWithModuleName:method.moduleName];
    NSMutableDictionary * option = [methodArguments[2] mutableCopy];
    [option setObject:method.moduleName forKey:@"moduleName"];
    // the value for moduleName in option is for the need of callback
    [self addModuleEventObservers:methodArguments[0] callback:methodArguments[1] option:option moduleClassName:NSStringFromClass(moduleClass)];
}

- (void)addModuleEventObservers:(NSString*)event callback:(NSString*)callbackId option:(NSDictionary *)option moduleClassName:(NSString*)moduleClassName
{
    BOOL once = [[option objectForKey:@"once"] boolValue];
    NSString * moduleName = [option objectForKey:@"moduleName"];
    NSMutableDictionary * observer = nil;
    NSDictionary * callbackInfo = @{@"callbackId":callbackId,@"once":@(once),@"moduleName":moduleName};
    if(![self checkModuleEventRegistered:event moduleClassName:moduleClassName]) {
        //had not registered yet
        observer = [NSMutableDictionary new];
        [observer setObject:[@{event:[@[callbackInfo] mutableCopy]} mutableCopy] forKey:moduleClassName];
        if (_moduleEventObservers[moduleClassName]) { //support multi event
            [_moduleEventObservers[moduleClassName] addEntriesFromDictionary:observer[moduleClassName]];
        }else {
            [_moduleEventObservers addEntriesFromDictionary:observer];
        }
    } else {
        observer = _moduleEventObservers[moduleClassName];
        [[observer objectForKey:event] addObject:callbackInfo];
    }
}

- (void)_removeModuleEventObserverWithModuleMethod:(WXModuleMethod *)method
{
    if (![method.arguments count] && [method.arguments[0] isKindOfClass:[NSString class]]) {
        return;
    }
    Class moduleClass =  [WXModuleFactory classWithModuleName:method.moduleName];
    [self removeModuleEventObserver:method.arguments[0] moduleClassName:NSStringFromClass(moduleClass)];
}

- (void)removeModuleEventObserver:(NSString*)event moduleClassName:(NSString*)moduleClassName
{
    if (![self checkModuleEventRegistered:event moduleClassName:moduleClassName]) {
        return;
    }
    [_moduleEventObservers[moduleClassName] removeObjectForKey:event];
}

- (void)moduleEventNotification:(NSNotification *)notification
{
    NSMutableDictionary *moduleEventObserversCpy = (NSMutableDictionary *)CFBridgingRelease(CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (CFDictionaryRef)_moduleEventObservers, kCFPropertyListMutableContainers));// deep
    NSDictionary * userInfo = notification.userInfo;
    NSMutableArray * listeners = [moduleEventObserversCpy[userInfo[@"moduleId"]] objectForKey:userInfo[@"eventName"]];
    if (![listeners isKindOfClass:[NSArray class]]) {
        return;
        // something wrong
    }
    for (int i = 0;i < [listeners count]; i ++) {
        NSDictionary * callbackInfo = listeners[i];
        NSString *callbackId = callbackInfo[@"callbackId"];
        BOOL once = [callbackInfo[@"once"] boolValue];
        NSDictionary * retData = @{@"type":userInfo[@"eventName"],
                                   @"module":callbackInfo[@"moduleName"],
                                   @"data":userInfo[@"param"]};
        [[WXSDKManager bridgeMgr] callBack:self.instanceId funcId:callbackId params:retData keepAlive:!once];
        // if callback function is not once, then it is keepalive
        if (once) {
            NSMutableArray * moduleEventListener = [_moduleEventObservers[userInfo[@"moduleId"]] objectForKey:userInfo[@"eventName"]];
            [moduleEventListener removeObject:callbackInfo];
            if ([moduleEventListener count] == 0) {
                [self removeModuleEventObserver:userInfo[@"eventName"] moduleClassName:userInfo[@"moduleId"]];
            }
            // if callback function is once. clear it after fire it.
        }
    }
}

- (void)addObservers
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moduleEventNotification:) name:WX_MODULE_EVENT_FIRE_NOTIFICATION object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
    [self addObserver:self forKeyPath:@"state" options:NSKeyValueObservingOptionNew context:NULL];
}

- (void)removeObservers
{
    @try {
        [self removeObserver:self forKeyPath:@"state" context:NULL];
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    @catch (NSException *exception) {//!OCLint
    }
}

- (void)applicationWillResignActive:(NSNotification*)notification
{
    [self fireGlobalEvent:WX_APPLICATION_WILL_RESIGN_ACTIVE params:nil];
}

- (void)applicationDidBecomeActive:(NSNotification*)notification
{
    [self fireGlobalEvent:WX_APPLICATION_DID_BECOME_ACTIVE params:nil];
}

- (WXComponentManager *)componentManager
{
    if (!_componentManager) {
        _componentManager = [[WXComponentManager alloc] initWithWeexInstance:self];
    }
    
    return _componentManager;
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"state"]) {
        WXState state = [change[@"new"] longValue];
        [self updateState:state];
        
        if (state == WeexInstanceDestroy) {
            [self destroyInstance];
        }
    }
}

- (void)willAppear
{
    if (self.isCustomRenderType) {
        if (!self.appearState) {
            // do create window,
            [[NSNotificationCenter defaultCenter] postNotificationName:WX_INSTANCE_NOTIFICATION_CHANGE_VISIBILITY_INTERNAL object:self userInfo:@{@"visible": @(YES)}];
            self.appearState = YES;
        }
    }
}

- (void)didDisappear
{
    if (self.isCustomRenderType) {
        if (self.appearState) {
            // do destroy window
            [[NSNotificationCenter defaultCenter] postNotificationName:WX_INSTANCE_NOTIFICATION_CHANGE_VISIBILITY_INTERNAL object:self userInfo:@{@"visible": @(NO)}];
            self.appearState = NO;
        }
    }
}

+ (NSDictionary*)lastPageInfo
{
    NSDictionary* result;
    @synchronized (lastPageInfoLock) {
        result = [lastPageInfo copy];
    }
    return result;
}

- (void)setAutoInvertingBehavior:(WXAutoInvertingBehavior)behavior
{
    _autoInvertingBehavior = behavior;
}

+ (id<WXDarkSchemeProtocol>)darkSchemeColorHandler
{
    return [WXHandlerFactory handlerForProtocol:@protocol(WXDarkSchemeProtocol)];
}

- (NSString*)currentSchemeName
{
    return self.schemeName;
}

- (BOOL)isDarkScheme
{
    return [self.schemeName isEqualToString:@"dark"];
}

- (void)registerModuleIntercept:(NSString*)moduleName callBack:(WXModuleInterceptCallback)callback {
    __weak WXSDKInstance* weakSelf = self;
    WXPerformBlockOnBridgeThread(^{
        __strong WXSDKInstance* strongSelf = weakSelf;
        if (strongSelf == nil) {
            return;
        }
        if (![WXUtility isBlankString:moduleName] && callback) {
            [strongSelf->_moduleIntercepts setObject:callback forKey:moduleName];
         }
    });
}

- (void)unRegisterModuleIntercept:(NSString*)moduleName {
    __weak WXSDKInstance* weakSelf = self;
    WXPerformBlockOnBridgeThread(^{
        __strong WXSDKInstance* strongSelf = weakSelf;
        if (strongSelf == nil) {
            return;
        }
        if (![WXUtility isBlankString:moduleName]) {
            [strongSelf->_moduleIntercepts removeObjectForKey:moduleName];
        }
    });
}

- (BOOL)moduleInterceptWithModuleName:(NSString*)moduleName methodName:(NSString*)methodName arguments:(NSArray*)arguments options:(NSDictionary*)options {
    WXAssertBridgeThread();
    if ([WXUtility isBlankString:moduleName]) {
        return NO;
    }
    WXModuleInterceptCallback callBack = [_moduleIntercepts objectForKey:moduleName];
    if (callBack) {
        return callBack(moduleName, methodName, arguments, options);
    }
    return NO;
}

- (void)setCurrentSchemeName:(NSString*)name
{
    if (![WXUtility isDarkSchemeSupportEnabled]) {
        self.schemeName = @"light";
        return;
    }
    
    if (name && ![name isEqualToString:self.schemeName]) {
        self.schemeName = name;
        
        if (self.isCustomRenderType) {
            return;
        }
        
        WXDarkSchemeModule* darkSchemeModule = [self moduleForClass:[WXDarkSchemeModule class]];
        [darkSchemeModule onInstanceSchemeChanged];
        
        // Recursively visit all components and notify that scheme had changed.
        __weak WXSDKInstance* weakSelf = self;
        WXPerformBlockOnComponentThread(^{
            __strong WXSDKInstance* strongSelf = weakSelf;
            if (strongSelf == nil) {
                return;
            }
            
            if (!strongSelf->_componentManager.isValid) {
                return;
            }
            
            [strongSelf->_componentManager enumerateComponentsUsingBlock:^(WXComponent * _Nonnull component, BOOL * _Nonnull stop) {
                __weak WXComponent* wcomp = component;
                WXPerformBlockOnMainThread(^{
                    __strong WXComponent* scomp = wcomp;
                    if (scomp) {
                        [scomp schemeDidChange:name];
                    }
                });
            }];
        });
        
        [[WXSDKManager bridgeMgr] fireEvent:_instanceId
                                        ref:WX_SDK_ROOT_REF
                                       type:@"schemechange"
                                     params:@{@"scheme": self.schemeName?:@"light"}
                                 domChanges:nil];
    }
}

- (UIColor*)chooseColor:(UIColor*)originalColor
       lightSchemeColor:(UIColor*)lightColor
        darkSchemeColor:(UIColor*)darkColor
                 invert:(BOOL)invert
                  scene:(WXColorScene)scene
{
    if (![WXUtility isDarkSchemeSupportEnabled]) {
        return originalColor;
    }
    
    if ([self isDarkScheme]) {
        if (darkColor) {
            return darkColor;
        }
        else if (invert) {
            // Invert originalColor
            if (originalColor == [UIColor clearColor]) {
                return originalColor;
            }
            return [[WXSDKInstance darkSchemeColorHandler] getInvertedColorFor:originalColor ofScene:scene withDefault:originalColor];
        }
        else {
            return originalColor;
        }
    }
    else if (lightColor) {
        return lightColor;
    }
    else {
        return originalColor;
    }
}

@end

@implementation WXSDKInstance (Deprecated)

# pragma mark - Deprecated

- (void)reloadData:(id)data
{
    [self refreshInstance:data];
}

- (void)finishPerformance
{
    //deprecated
}

- (void)creatFinish
{
    
}

@end
