/*
 * 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 "WXBridgeManager.h"
#import "WXBridgeContext.h"
#import "WXLog.h"
#import "WXAssert.h"
#import "WXBridgeMethod.h"
#import "WXCallJSMethod.h"
#import "WXSDKManager.h"
#import "WXSDKInstance_private.h"
#import "WXServiceFactory.h"
#import "WXResourceRequest.h"
#import "WXResourceLoader.h"
#import "WXDebugTool.h"
#import "WXMonitor.h"
#import "WXSDKInstance_performance.h"
#import "WXThreadSafeMutableArray.h"
#import "WXComponentManager.h"
#import "WXCoreBridge.h"
#import "WXHandlerFactory.h"
#import "WXUtility.h"
#import "WXExceptionUtils.h"
#import "WXSDKEngine.h"
#import "WXConfigCenterProtocol.h"

@interface WXBridgeManager ()

@property (nonatomic, assign) BOOL stopRunning;
@property (nonatomic, assign) BOOL supportMultiJSThread;
@property (nonatomic, strong) WXBridgeContext *bridgeCtx;
@property (nonatomic, strong) WXBridgeContext *backupBridgeCtx;
@property (nonatomic, strong) WXThreadSafeMutableArray *instanceIdStack;
@property (nonatomic, strong) NSMutableArray* jsTaskQueue;
@property (nonatomic, strong) NSTimer *timer;

@end

static NSThread *WXBridgeThread;
static NSThread *WXBackupBridgeThread;

@implementation WXBridgeManager

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

- (instancetype)init
{
    self = [super init];
    if (self) {
        _bridgeCtx = [[WXBridgeContext alloc] init];
        _supportMultiJSThread = NO;
        _jsTaskQueue = [NSMutableArray array];
        _timer = nil;
        _lastMethodInfo = [NSMutableDictionary dictionary];
    }
    return self;
}

- (WXBridgeContext *)bridgeCtx {
    if (_bridgeCtx) {
        return _bridgeCtx;
    }
    _bridgeCtx = [[WXBridgeContext alloc] init];
    return _bridgeCtx;
}

- (WXBridgeContext *)backupBridgeCtx {
    if (_backupBridgeCtx) {
        return _backupBridgeCtx;
    }
    if (!_supportMultiJSThread) {
        _backupBridgeCtx = _bridgeCtx;
    } else {
        _backupBridgeCtx = [[WXBridgeContext alloc] init];
    }
    return _backupBridgeCtx;
}

- (WXSDKInstance *)topInstance
{
    return _bridgeCtx.topInstance;
}

- (void)unload
{
    _bridgeCtx = nil;
    _backupBridgeCtx = nil;
}

#pragma mark Thread Management

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

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

    return WXBridgeThread;
}

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

    return WXBackupBridgeThread;
}

void WXPerformBlockOnBridgeThread(void (^block)(void))
{
    [WXBridgeManager _performBlockOnBridgeThread:block];
}

void WXPerformBlockOnBridgeThreadForInstance(void (^block)(void), NSString* instance) {
    [WXBridgeManager _performBlockOnBridgeThread:block instance:instance];
}

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

+ (void)_performBlockOnBridgeThread:(void (^)(void))block instance:(NSString*)instanceId
{
    if (![WXSDKManager bridgeMgr].supportMultiJSThread) {
        if ([NSThread currentThread] == [self jsThread]) {
            block();
        } else {
            [self performSelector:@selector(_performBlockOnBridgeThread:instance:)
                         onThread:[self jsThread]
                       withObject:[block copy]
                    waitUntilDone:NO];
       }
        return;
    }

    if ([NSThread currentThread] == [self jsThread] || [NSThread currentThread] == [self backupJsThread]) {
        block();
    } else {
        WXSDKInstance* instance = nil;
        if (instanceId) {
            instance = [WXSDKManager instanceForID:instanceId];
        }

        if (instance && instance.useBackupJsThread) {
            [self performSelector:@selector(_performBlockOnBridgeThread:instance:)
                         onThread:[self backupJsThread]
                       withObject:[block copy]
                    waitUntilDone:NO];
        } else {
            [self performSelector:@selector(_performBlockOnBridgeThread:instance:)
                         onThread:[self jsThread]
                       withObject:[block copy]
                    waitUntilDone:NO];
        }
    }
}

void WXPerformBlockOnBackupBridgeThread(void (^block)(void))
{
    [WXBridgeManager _performBlockOnBackupBridgeThread:block putInTaskQueue:YES];
}

+ (void)_performBlockOnBackupBridgeThread:(void (^)(void))block putInTaskQueue:(BOOL)putInTaskQueue
{
    if (![WXSDKManager bridgeMgr].supportMultiJSThread) {
        return;
    }
    if (putInTaskQueue) {
        [WXBridgeManager _performBlockOnBackupBridgeThread:^{
            [[WXSDKManager bridgeMgr].jsTaskQueue addObject:block];
        } putInTaskQueue:NO];
    } else {
        if ([NSThread currentThread] == [self backupJsThread]) {
            block();
        } else {
            [self performSelector:@selector(_performBlockOnBridgeThread:instance:)
                         onThread:[self backupJsThread]
                       withObject:[block copy]
                    waitUntilDone:NO];
        }
    }
}

void WXPerformBlockSyncOnBridgeThread(void (^block) (void)) {
    [WXBridgeManager _performBlockSyncOnBridgeThread:block];
}

void WXPerformBlockSyncOnBridgeThreadForInstance(void (^block) (void), NSString* instance)
{
    [WXBridgeManager _performBlockSyncOnBridgeThread:block instance:instance];
}

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

+ (void)_performBlockSyncOnBridgeThread:(void (^)(void))block instance:(NSString*)instanceId
{
    if (![WXSDKManager bridgeMgr].supportMultiJSThread) {
        if ([NSThread currentThread] == [self jsThread]) {
            block();
        } else {
            [self performSelector:@selector(_performBlockSyncOnBridgeThread:instance:)
                         onThread:[self jsThread]
                       withObject:[block copy]
                    waitUntilDone:YES];
        }
        return;
    }

    if ([NSThread currentThread] == [self jsThread] || [NSThread currentThread] == [self backupJsThread]) {
        block();
    } else {
        WXSDKInstance* instance = nil;
        if (instanceId) {
            instance = [WXSDKManager instanceForID:instanceId];
        }

        if (instance && instance.useBackupJsThread) {
            [self performSelector:@selector(_performBlockSyncOnBridgeThread:instance:)
                         onThread:[self backupJsThread]
                       withObject:[block copy]
                    waitUntilDone:YES];
        } else {
            [self performSelector:@selector(_performBlockSyncOnBridgeThread:instance:)
                         onThread:[self jsThread]
                       withObject:[block copy]
                    waitUntilDone:YES];
        }
    }
}

#pragma mark JSBridge Management
- (void)createInstanceForJS:(NSString *)instance
              template:(NSString *)temp
               options:(NSDictionary *)options
                  data:(id)data {
    if (!instance || !temp) return;
    __weak typeof(self) weakSelf = self;
    NSMutableDictionary *newOptions = [options mutableCopy] ?: [NSMutableDictionary new];
    newOptions[@"EXEC_JS"] = @(YES);
    WXPerformBlockOnBridgeThreadForInstance(^(){
        WXSDKInstance* sdkInstance = [WXSDKManager instanceForID:instance];
        if (!sdkInstance) {
            return;
        }
        WXBridgeContext* context = sdkInstance.useBackupJsThread ? weakSelf.backupBridgeCtx :  weakSelf.bridgeCtx;
        [context createInstance:instance
                                  template:temp
                                   options:newOptions
                                      data:data];
    }, instance);
}

- (void)createInstance:(NSString *)instance
              template:(NSString *)temp
               options:(NSDictionary *)options
                  data:(id)data
{
    if (!instance || !temp) return;
    if (![self.instanceIdStack containsObject:instance]) {
        if ([options[@"RENDER_IN_ORDER"] boolValue]) {
            [self.instanceIdStack addObject:instance];
        } else {
            [self.instanceIdStack insertObject:instance atIndex:0];
        }
    }
    //third team impl...
    WXSDKInstance* sdkInstance = [WXSDKManager instanceForID:instance];
    if (sdkInstance) {
        sdkInstance.apmInstance.isStartRender = YES;
    }
    __weak typeof(self) weakSelf = self;
    WXPerformBlockOnBridgeThreadForInstance(^(){
        WXBridgeContext* context = sdkInstance.useBackupJsThread ? weakSelf.backupBridgeCtx :  weakSelf.bridgeCtx;
        [context createInstance:instance
                                  template:temp
                                   options:options
                                      data:data];
    }, instance);
}

- (void)createInstance:(NSString *)instance
              contents:(NSData *)contents
               options:(NSDictionary *)options
                  data:(id)data
{
    if (!instance || !contents) return;
    if (![self.instanceIdStack containsObject:instance]) {
        if ([options[@"RENDER_IN_ORDER"] boolValue]) {
            [self.instanceIdStack addObject:instance];
        } else {
            [self.instanceIdStack insertObject:instance atIndex:0];
        }
    }
    //third team impl...
    WXSDKInstance* sdkInstance = [WXSDKManager instanceForID:instance];
    if (sdkInstance) {
        sdkInstance.apmInstance.isStartRender = YES;
    }
    __weak typeof(self) weakSelf = self;
    WXPerformBlockOnBridgeThreadForInstance(^(){
        WXBridgeContext* context = sdkInstance.useBackupJsThread ? weakSelf.backupBridgeCtx :  weakSelf.bridgeCtx;
        [context createInstance:instance
                                  contents:contents
                                   options:options
                                      data:data];
    }, instance);
}

- (void)executeJSTaskQueue {
    __weak typeof(self) weakSelf = self;
    [WXBridgeManager _performBlockOnBackupBridgeThread:^{
        if (weakSelf.jsTaskQueue.count == 0 || !weakSelf.supportMultiJSThread) {
            return;
        }
        for (id task in weakSelf.jsTaskQueue) {
            void (^block)(void) = task;
            block();
        }
        [weakSelf.jsTaskQueue removeAllObjects];
    } putInTaskQueue:NO];
}

- (WXThreadSafeMutableArray *)instanceIdStack
{
    if (_instanceIdStack) return _instanceIdStack;
    
    _instanceIdStack = [[WXThreadSafeMutableArray alloc] init];
    
    return _instanceIdStack;
}

- (NSArray *)getInstanceIdStack;
{
    return [self.instanceIdStack copy];
}

- (void)destroyInstance:(NSString *)instance
{
    if (!instance) return;
    [self.instanceIdStack removeObject:instance];
    
    __weak typeof(self) weakSelf = self;
    WXPerformBlockOnBridgeThreadForInstance(^(){
        WXSDKInstance* sdkInstance = [WXSDKManager instanceForID:instance];
        WXBridgeContext* context = sdkInstance.useBackupJsThread ? weakSelf.backupBridgeCtx :  weakSelf.bridgeCtx;
        [context destroyInstance:instance];
    }, instance);
}

- (void)forceGarbageCollection
{
    __weak typeof(self) weakSelf = self;
    WXPerformBlockOnBridgeThread(^(){
        [weakSelf.bridgeCtx forceGarbageCollection];
    });
}

- (void)refreshInstance:(NSString *)instance
                   data:(NSDictionary *)data
{
    if (!instance) return;
    
    __weak typeof(self) weakSelf = self;
    WXPerformBlockOnBridgeThreadForInstance(^(){
        WXSDKInstance* sdkInstance = [WXSDKManager instanceForID:instance];
        WXBridgeContext* context = sdkInstance.useBackupJsThread ? weakSelf.backupBridgeCtx :  weakSelf.bridgeCtx;
        [context refreshInstance:instance data:data];
    }, instance);
}

- (void)updateState:(NSString *)instance data:(id)data
{
    if (!instance) return;
    
    __weak typeof(self) weakSelf = self;
    WXPerformBlockOnBridgeThreadForInstance(^(){
        WXSDKInstance* sdkInstance = [WXSDKManager instanceForID:instance];
        WXBridgeContext* context = sdkInstance && sdkInstance.useBackupJsThread ? weakSelf.backupBridgeCtx :  weakSelf.bridgeCtx;
        [context updateState:instance data:data];
    }, instance);
}

- (void)executeJsFramework:(NSString *)script
{
    if (!script) return;
    
    __weak typeof(self) weakSelf = self;
    WXPerformBlockOnBridgeThread(^(){
        [weakSelf.bridgeCtx executeJsFramework:script];
    });
    WXPerformBlockOnBackupBridgeThread(^{
        [weakSelf.backupBridgeCtx executeJsFramework:script];
    });
}

- (void)callJsMethod:(WXCallJSMethod *)method
{
    if (!method || !method.instance) return;
    
    __weak typeof(self) weakSelf = self;
    WXPerformBlockOnBridgeThreadForInstance(^(){
        WXBridgeContext* context = method.instance.useBackupJsThread ? weakSelf.backupBridgeCtx :  weakSelf.bridgeCtx;
        [context executeJsMethod:method];
    }, method.instance.instanceId);
}

- (JSValue *)callJSMethodWithResult:(WXCallJSMethod *)method
{
    if (!method || !method.instance) return nil;
    __weak typeof(self) weakSelf = self;
    __block JSValue *value;
    WXPerformBlockSyncOnBridgeThreadForInstance(^(){
        WXBridgeContext* context = method.instance.useBackupJsThread ? weakSelf.backupBridgeCtx :  weakSelf.bridgeCtx;
        value = [context excuteJSMethodWithResult:method];
    }, method.instance.instanceId);
    return value;
}

- (void)DownloadJS:(NSString*)instance url:(NSURL *)scriptUrl completion:(void (^)(NSString *script))complection;
{
    if (!scriptUrl || ![scriptUrl.absoluteString length]) {
        if (complection) {
            complection(nil);
        }
        return;
    }
    WXResourceRequest* request = [WXResourceRequest requestWithURL:scriptUrl];
    WXResourceLoader* jsLoader = [[WXResourceLoader alloc] initWithRequest:request];
    jsLoader.onFinished = ^(WXResourceResponse *response, NSData *data) {
        NSString* jsString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        if (complection) {
            complection(jsString);
        }
    };
    jsLoader.onFailed = ^(NSError *loadError) {
        if (complection) {
            complection(nil);
        }

        WXSDKInstance *sdkInstance = [WXSDKManager instanceForID:instance];
        WXComponentManager *manager = sdkInstance.componentManager;
        if (manager.isValid) {
            NSString *errorMessage = [NSString stringWithFormat:@"Request to %@ occurs an error:%@, info:%@", request.URL, loadError.localizedDescription, loadError.userInfo];
            WXSDKErrCode errorCode = WX_KEY_EXCEPTION_JS_DOWNLOAD;
            NSError *error = [NSError errorWithDomain:WX_ERROR_DOMAIN code:errorCode userInfo:@{NSLocalizedDescriptionKey:(errorMessage?:@"No message")}];
            WXPerformBlockOnComponentThread(^{
                [manager renderFailed:error];
            });
        }
    };

   [jsLoader start];
}

- (void)registerService:(NSString *)name withServiceUrl:(NSURL *)serviceScriptUrl withOptions:(NSDictionary *)options completion:(void(^)(BOOL result))completion
{
    if (!name || !serviceScriptUrl || !options) {
        if (completion) {
            completion(NO);
        }
        return;
    }
    __weak typeof(self) weakSelf = self;
    WXResourceRequest *request = [WXResourceRequest requestWithURL:serviceScriptUrl resourceType:WXResourceTypeServiceBundle referrer:@"" cachePolicy:NSURLRequestUseProtocolCachePolicy];
    WXResourceLoader *serviceBundleLoader = [[WXResourceLoader alloc] initWithRequest:request];;
    serviceBundleLoader.onFinished = ^(WXResourceResponse *response, NSData *data) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        NSString *jsServiceString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        [strongSelf registerService:name withService:jsServiceString withOptions:options completion:completion];
    };
    
    serviceBundleLoader.onFailed = ^(NSError *loadError) {
        WXLogError(@"No script URL found");
        if (completion) {
            completion(NO);
        }
    };
    
    [serviceBundleLoader start];
}

- (void)registerService:(NSString *)name withService:(NSString *)serviceScript withOptions:(NSDictionary *)options completion:(void(^)(BOOL result))completion
{
    WXLogInfo(@"Register service: %@, options: %@", name, options);
    
    if (!name || !serviceScript || !options) {
        if (completion) {
            completion(NO);
        }
        return;
    }
    
    NSString *script = [WXServiceFactory registerServiceScript:name withRawScript:serviceScript withOptions:options];
    
    __weak typeof(self) weakSelf = self;
    WXPerformBlockOnBridgeThread(^(){
        // save it when execute
        [WXDebugTool cacheJsService:name withScript:serviceScript withOptions:options];
        [weakSelf.bridgeCtx executeJsService:script withName:name];
        if (completion) {
            completion(YES);
        }
    });
    WXPerformBlockOnBackupBridgeThread(^(){
        [weakSelf.backupBridgeCtx executeJsService:script withName:name];
    });
}

- (void)unregisterService:(NSString *)name
{
    if (!name) return;
    
    WXLogInfo(@"Unregister service: %@", name);
    NSString *script = [WXServiceFactory unregisterServiceScript:name];
    
    __weak typeof(self) weakSelf = self;
    WXPerformBlockOnBridgeThread(^(){
        // save it when execute
        [WXDebugTool removeCacheJsService:name];
        [weakSelf.bridgeCtx executeJsService:script withName:name];
    });
    WXPerformBlockOnBackupBridgeThread(^(){
        [weakSelf.backupBridgeCtx executeJsService:script withName:name];
    });
}

- (void)registerModules:(NSDictionary *)modules
{
    if (!modules) return;
    
    modules = [WXUtility convertContainerToImmutable:modules];
    WXLogInfo(@"Register modules: %@", modules);
    
    __weak typeof(self) weakSelf = self;
    WXPerformBlockOnBridgeThread(^(){
        [weakSelf.bridgeCtx registerModules:modules];
    });
    WXPerformBlockOnBackupBridgeThread(^(){
        [weakSelf.backupBridgeCtx registerModules:modules];
    });
}

- (void)registerComponents:(NSArray *)components
{
    if (!components) return;
    
    components = [WXUtility convertContainerToImmutable:components];
    WXLogInfo(@"Register components: %@", components);
    
    __weak typeof(self) weakSelf = self;
    WXPerformBlockOnBridgeThread(^(){
        [weakSelf.bridgeCtx registerComponents:components];
    });
    WXPerformBlockOnBackupBridgeThread(^(){
        [weakSelf.backupBridgeCtx registerComponents:components];
    });
}

- (void)fireEvent:(NSString *)instanceId ref:(NSString *)ref type:(NSString *)type params:(NSDictionary *)params
{
    [self fireEvent:instanceId ref:ref type:type params:params domChanges:nil];
}

- (void)fireEvent:(NSString *)instanceId ref:(NSString *)ref type:(NSString *)type params:(NSDictionary *)params domChanges:(NSDictionary *)domChanges
{
    [self fireEvent:instanceId ref:ref type:type params:params domChanges:domChanges handlerArguments:nil];
}

- (void)fireEvent:(NSString *)instanceId ref:(NSString *)ref type:(NSString *)type params:(NSDictionary *)params domChanges:(NSDictionary *)domChanges handlerArguments:(NSArray *)handlerArguments
{
    WXSDKInstance *instance = [WXSDKManager instanceForID:instanceId];
    if (instance.renderPlugin.isSupportFireEvent) {
        WXPerformBlockOnComponentThread(^{
            [instance.renderPlugin fireEvent:instanceId ref:ref event:type args:params?:@{} domChanges:domChanges?:@{}];
        });
        return;
    }

    if (!type || !ref) {
        WXLogError(@"Event type and component ref should not be nil");
        return;
    }
    
    NSArray *args = @[ref, type, params?:@{}, domChanges?:@{}];
    if (handlerArguments) {
        NSMutableArray *newArgs = [args mutableCopy];
        [newArgs addObject:@{@"params":handlerArguments}];
        args = newArgs;
    }
    
    if(instance && !instance.isJSCreateFinish)
    {
        instance.performance.fsCallEventNum++;
    }
    if (instance && !instance.apmInstance.isFSEnd) {
        [instance.apmInstance updateFSDiffStats:KEY_PAGE_STATS_FS_CALL_EVENT_NUM withDiffValue:1];
    }
    
    WXCallJSMethod *method = [[WXCallJSMethod alloc] initWithModuleName:nil methodName:@"fireEvent" arguments:[WXUtility convertContainerToImmutable:args] instance:instance];
    [self callJsMethod:method];
}

- (void)callComponentHook:(NSString*)instanceId componentId:(NSString*)componentId type:(NSString*)type hook:(NSString*)hookPhase args:(NSArray*)args competion:(void (^)(JSValue * value))completion
{
     __weak typeof(self) weakSelf = self;
    WXPerformBlockOnBridgeThreadForInstance(^{
        if (!type || !instanceId || !hookPhase) {
            WXLogError(@"type and instance id and hookPhase should not be nil");
            return;
        }
        NSArray *newArgs = @[componentId, type, hookPhase, args?:@[]];
        
        WXCallJSMethod * method = [[WXCallJSMethod alloc] initWithModuleName:nil methodName:@"componentHook" arguments:newArgs instance:[WXSDKManager instanceForID:instanceId]];
        WXSDKInstance* sdkInstance =  [WXSDKManager instanceForID:instanceId];
        WXBridgeContext* context = sdkInstance.useBackupJsThread ? weakSelf.backupBridgeCtx :  weakSelf.bridgeCtx;
        [context callJSMethod:@"callJS" args:@[instanceId, @[method.callJSTask]] onContext:nil completion:completion];
    }, instanceId);
}

- (JSValue *)fireEventWithResult:(NSString *)instanceId ref:(NSString *)ref type:(NSString *)type params:(NSDictionary *)params domChanges:(NSDictionary *)domChanges
{
    if (!type || !ref) {
        WXLogError(@"Event type and component ref should not be nil");
        return nil;
    }
    NSArray *args = @[ref, type, params?:@{}, domChanges?:@{}];
    WXSDKInstance *instance = [WXSDKManager instanceForID:instanceId];
    WXCallJSMethod *method = [[WXCallJSMethod alloc] initWithModuleName:nil methodName:@"fireEvent" arguments:args instance:instance];
    return [self callJSMethodWithResult:method];
}

- (void)callBack:(NSString *)instanceId funcId:(NSString *)funcId params:(id)params keepAlive:(BOOL)keepAlive
{
    NSArray *args = nil;
    if (keepAlive) {
        args = @[[funcId copy], params? [params copy]:@"\"{}\"", @true];
    } else {
        args = @[[funcId copy], params? [params copy]:@"\"{}\""];
    }
    WXSDKInstance *instance = [WXSDKManager instanceForID:instanceId];
    if (instance.renderPlugin.isSupportInvokeJSCallBack) {
        id strongArgs = params ? [params copy]:@"\"{}\"";
        WXPerformBlockOnComponentThread(^{
            [instance.renderPlugin invokeCallBack:instanceId function:funcId args:strongArgs keepAlive:keepAlive];
        });
    }
    else {
        WXCallJSMethod *method = [[WXCallJSMethod alloc] initWithModuleName:@"jsBridge" methodName:@"callback" arguments:args instance:instance];
        [self callJsMethod:method];
    }
}

- (void)callBack:(NSString *)instanceId funcId:(NSString *)funcId params:(id)params
{
    [self callBack:instanceId funcId:funcId params:params keepAlive:NO];
}

- (void)connectToDevToolWithUrl:(NSURL *)url {
    WXPerformBlockOnBridgeThread(^(){
        [self.bridgeCtx connectToDevToolWithUrl:url];
    });
}

- (void)connectToWebSocket:(NSURL *)url
{
    __weak typeof(self) weakSelf = self;
    WXPerformBlockOnBridgeThread(^(){
        [weakSelf.bridgeCtx connectToWebSocket:url];
    });
}

- (void)logToWebSocket:(NSString *)flag message:(NSString *)message
{
    if (!message) return;
    
    __weak typeof(self) weakSelf = self;
    WXPerformBlockOnBridgeThread(^(){
        [weakSelf.bridgeCtx logToWebSocket:flag message:message];
    });
}

- (void)resetEnvironment
{
    __weak typeof(self) weakSelf = self;
    WXPerformBlockOnBridgeThread(^(){
        [weakSelf.bridgeCtx resetEnvironment];
    });
    WXPerformBlockOnBackupBridgeThread(^(){
        [weakSelf.backupBridgeCtx resetEnvironment];
    });
}

- (void)callJSMethod:(NSString *)method args:(NSArray *)args
{
    if (!method) return;

    __weak typeof(self) weakSelf = self;
    NSString* instanceId = args[0];
    WXPerformBlockOnBridgeThreadForInstance(^(){
        WXSDKInstance* sdkInstance = [WXSDKManager instanceForID:instanceId];
        WXBridgeContext* context = sdkInstance && sdkInstance.useBackupJsThread ? weakSelf.backupBridgeCtx :  weakSelf.bridgeCtx;
        [context callJSMethod:method args:args onContext:nil completion:nil];
    }, instanceId);
}

#pragma mark JS Thread Check
- (void)checkJSThread {
    if (!_timer) {
        id configCenter = [WXSDKEngine handlerForProtocol:@protocol(WXConfigCenterProtocol)];
        if ([configCenter respondsToSelector:@selector(configForKey:defaultValue:isDefault:)]) {
            BOOL enableCheckJSThread = [[configCenter configForKey:@"iOS_weex_ext_config.enable_check_js_thread" defaultValue:@(YES) isDefault:NULL] boolValue];
            if (enableCheckJSThread) {
                _timer = [NSTimer scheduledTimerWithTimeInterval:5.0f target:self selector:@selector(_postTaskToBridgeThread) userInfo:nil repeats:YES];
            }
        }
    }
}

- (void)_postTaskToBridgeThread {
    __block BOOL taskFinished = NO;
    WXPerformBlockOnBridgeThread(^{
        taskFinished = YES;
    });

    __weak typeof(self) weakSelf = self;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        if (!weakSelf) {
            return;
        }
        if (!taskFinished) {
            WXSDKErrCode errorCode = WX_KEY_EXCEPTION_JS_THREAD_BLOCK;
            WXSDKInstance* instance = weakSelf.topInstance;
            if (!instance) {
                return;
            }
            NSString *instanceId = instance.instanceId;
            [WXExceptionUtils commitCriticalExceptionRT:instanceId errCode:[NSString stringWithFormat:@"%d", errorCode] function:@"" exception:@"JS Thread is block" extParams:weakSelf.lastMethodInfo];
        }
    });
}

#pragma mark - Deprecated

- (void)executeJsMethod:(WXCallJSMethod *)method
{
    if (!method || !method.instance) return;
    
    __weak typeof(self) weakSelf = self;
    WXPerformBlockOnBridgeThreadForInstance(^(){
        WXBridgeContext* context = method.instance.useBackupJsThread ? weakSelf.backupBridgeCtx :  weakSelf.bridgeCtx;
        [context executeJsMethod:method];
    }, method.instance.instanceId);
}

@end
