/*
 * 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 "WXSDKError.h"
#import "WXCoreBridge.h"
#import "JSValue+Weex.h"
#import "WXSDKManager.h"
#import "WXComponentManager.h"
#import "WXSDKInstance_private.h"
#import "WXLog.h"
#import "WXBridgeProtocol.h"
#import "WXUtility.h"
#import "WXAssert.h"
#import "WXAppConfiguration.h"
#import "WXConvertUtility.h"
#import "WXSDKEngine.h"
#import "WXAppMonitorProtocol.h"
#import "WXComponentMethod.h"
#import "WXExceptionUtils.h"
#import "WXModuleFactory.h"
#import "WXComponentFactory.h"
#import "WXRichText.h"
#include "base/core_constants.h"
#include "base/time_utils.h"
#include "base/log_defines.h"
#include "core/manager/weex_core_manager.h"
#include "core/render/manager/render_manager.h"
#include "core/render/target/render_target.h"
#include "core/render/page/render_page.h"
#include "core/render/page/render_page_custom.h"
#include "core/render/node/render_object.h"
#include "core/render/node/render_list.h"
#include "core/render/node/factory/render_type.h"
#include "core/render/node/factory/render_creator.h"
#include "core/config/core_environment.h"
#include "core/bridge/platform/core_side_in_platform.h"
#include "core/bridge/script/core_side_in_script.h"
#include "core/network/http_module.h"

#import <objc/runtime.h>
#include <fstream>

namespace WeexCore
{    
    static void consoleWithArguments(NSArray *arguments, WXLogFlag logLevel)
    {
        NSMutableString *jsLog = [NSMutableString string];
        [jsLog appendString:@"jsLog: "];
        [arguments enumerateObjectsUsingBlock:^(NSString *jsVal, NSUInteger idx, BOOL *stop) {
            if (idx == arguments.count - 1) {
                if (logLevel) {
                    if (WXLogFlagWarning == logLevel || WXLogFlagError == logLevel) {
                        id<WXAppMonitorProtocol> appMonitorHandler = [WXSDKEngine handlerForProtocol:@protocol(WXAppMonitorProtocol)];
                        if ([appMonitorHandler respondsToSelector:@selector(commitAppMonitorAlarm:monitorPoint:success:errorCode:errorMsg:arg:)]) {
                            [appMonitorHandler commitAppMonitorAlarm:@"weex" monitorPoint:@"jswarning" success:NO errorCode:@"99999" errorMsg:jsLog arg:[WXSDKEngine topInstance].pageName];
                        }
                    }
                    WX_LOG(logLevel, @"%@", jsLog);
                }
                else {
                    [jsLog appendFormat:@"%@ ", jsVal];
                    WXLogInfo(@"%@", jsLog);
                }
            }
            else {
                [jsLog appendFormat:@"%@ ", jsVal];
            }
        }];
    }
    
    static void MergeBorderWidthValues(NSMutableDictionary* dict,
                                       const WXCoreBorderWidth & borders,
                                       bool isUpdate, float pixelScaleFactor)
    {
        if (pixelScaleFactor <= 0) {
            pixelScaleFactor = 1.0f;
        }
        if (borders.getBorderWidth(kBorderWidthTop) != (float)0.0f || isUpdate) {
            dict[@"borderTopWidth"] = @(borders.getBorderWidth(kBorderWidthTop) / pixelScaleFactor);
        }
        if (borders.getBorderWidth(kBorderWidthLeft) != (float)0.0f || isUpdate) {
            dict[@"borderLeftWidth"] = @(borders.getBorderWidth(kBorderWidthLeft) / pixelScaleFactor);
        }
        if (borders.getBorderWidth(kBorderWidthBottom) != (float)0.0f || isUpdate) {
            dict[@"borderBottomWidth"] = @(borders.getBorderWidth(kBorderWidthBottom) / pixelScaleFactor);
        }
        if (borders.getBorderWidth(kBorderWidthRight) != (float)0.0f || isUpdate) {
            dict[@"borderRightWidth"] = @(borders.getBorderWidth(kBorderWidthRight) / pixelScaleFactor);
        }
    }

    static void MergeBorderWidthValues(NSMutableDictionary* dict,
                                       std::vector<std::pair<std::string, std::string>>* borders,
                                       float pixelScaleFactor)
    {
        if (borders == nullptr) {
            return;
        }
        if (pixelScaleFactor <= 0) {
            pixelScaleFactor = 1.0f;
        }
        
        for (auto& p : *borders) {
            dict[NSSTRING(p.first.c_str())] = @(atof(p.second.c_str()) / pixelScaleFactor);
        }
    }

    void IOSSide::SetJSVersion(const char* version)
    {
        NSString *jsVersion = NSSTRING(version);
        if (jsVersion.length > 0) {
            [WXAppConfiguration setJSFrameworkVersion:jsVersion];
        }
    }
    
    void IOSSide::ReportException(const char *page_id, const char *func, const char *exception)
    {
        do {
            WXSDKInstance *instance = [WXSDKManager instanceForID:NSSTRING(page_id)];
            if (!instance) {
                break;
            }
            WXSDKErrCode errorCode = WX_ERR_JS_EXECUTE;
            BOOL is_render_failed = NO;
            if (func && (strcmp(func, "CreatePageWithContent") == 0 || strcmp(func, "UpdateComponentData") == 0)) {
                errorCode = WX_KEY_EXCEPTION_DEGRADE_EAGLE_RENDER_ERROR;
                WXComponentManager *manager = instance.componentManager;
                if (manager.isValid) {
                    NSError *error = [NSError errorWithDomain:WX_ERROR_DOMAIN code:errorCode userInfo:@{@"message":[NSString stringWithUTF8String:exception], @"exception function:":@(func)}];
                    [manager renderFailed:error];
                }
                is_render_failed = YES;
            }
            NSString *bundleUrl = instance.pageName ? : ([instance.scriptURL absoluteString] ? : @"WX_KEY_EXCEPTION_WXBRIDGE");
            NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
            [userInfo setObject:instance.userInfo[@"jsMainBundleStringContentLength"] ? : @"" forKey:@"jsMainBundleStringContentLength"];
            [userInfo setObject:instance.userInfo[@"jsMainBundleStringContentMd5"] ? : @"" forKey:@"jsMainBundleStringContentMd5"];
            WXJSExceptionInfo *jsException = [[WXJSExceptionInfo alloc] initWithInstanceId:instance.instanceId bundleUrl:bundleUrl errorCode: [NSString stringWithFormat:@"%d", errorCode] functionName:func ? [NSString stringWithUTF8String:func] :@"exceptionHandler" exception:exception ? [NSString stringWithUTF8String:exception] : @"unkown" userInfo:userInfo];
            [WXExceptionUtils commitCriticalExceptionRT:jsException.instanceId errCode:jsException.errorCode function:jsException.functionName exception:jsException.exception extParams:jsException.userInfo];
            if (!is_render_failed && instance.onJSRuntimeException) {
                instance.onJSRuntimeException(jsException);
            }
            
        } while (0);
        
    }
    
    int IOSSide::CallNative(const char* pageId, const char *task, const char *callback)
    {
        // should not enter this function
        assert(false); //!OCLint
    }
    
    static WeexByteArray *generator_bytes_array(const char *str, size_t len) {
        auto *result = (WeexByteArray *)malloc(len + sizeof(WeexByteArray));
        do {
            if (!result) {
                break;
            }
            memset(result, 0, len + sizeof(WeexByteArray));
            result->length = static_cast<uint32_t>(len);
            memcpy(result->content, str, len);
            result->content[len] = '\0';
            
        } while (0);
        
        return result;
    }
    std::unique_ptr<ValueWithType> IOSSide::RegisterPluginComponent(const char *pcstr_name, const char *pcstr_class_name, const char *pcstr_version) {
        ValueWithType *returnValue = new ValueWithType();
        memset(returnValue, 0, sizeof(ValueWithType));
        returnValue->type = ParamsType::VOID;
        do {
            if (!pcstr_class_name) {
                break;
            }
            NSString *className = [NSString stringWithUTF8String:pcstr_class_name];
            Class clazz = NSClassFromString(className);
            if (!clazz) {
                break;
            }
            if (!pcstr_name) {
                break;
            }
            NSDictionary *properties = @{ @"append" : @"tree" };
            NSString *name = [NSString stringWithUTF8String:pcstr_name];
            [WXComponentFactory registerComponent:name withClass:clazz withPros:properties];
            NSMutableDictionary *info = [WXComponentFactory componentMethodMapsWithName:name];
            if (![info isKindOfClass:[NSDictionary class]]) {
                break;
            }
            NSArray *methods = info[@"methods"];
            if (![methods isKindOfClass:[NSArray class]] || !methods.count) {
                break;
            }
            info[@"type"] = name;
            NSMutableDictionary *props = [properties mutableCopy];
            [props addEntriesFromDictionary:info];
            NSString *componentsInfo = [WXUtility JSONString:@[props]];
            if (componentsInfo.length > 0) {
                returnValue->type = ParamsType::BYTEARRAYSTRING;
                const char *pcstr_utf8 = [componentsInfo UTF8String];
                returnValue->value.byteArray = generator_bytes_array(pcstr_utf8, componentsInfo.length);
            }
            
        } while (0);
        
        return std::unique_ptr<ValueWithType>(returnValue);
    }
    
    std::unique_ptr<ValueWithType> IOSSide::RegisterPluginModule(const char *pcstr_name, const char *pcstr_class_name, const char *pcstr_version) {
        ValueWithType *returnValue = new ValueWithType();
        memset(returnValue, 0, sizeof(ValueWithType));
        returnValue->type = ParamsType::VOID;
        do {
            if (!pcstr_class_name) {
                break;
            }
            NSString *className = [NSString stringWithUTF8String:pcstr_class_name];
            Class clazz = NSClassFromString(className);
            if (!clazz) {
                break;
            }
            if (!pcstr_name) {
                break;
            }
            NSString *name = [NSString stringWithUTF8String:pcstr_name];
            NSString *moduleName = [WXModuleFactory registerModule:name withClass:clazz];
            if (!moduleName.length) {
                break;
            }
            NSDictionary *moduleInfo = [WXModuleFactory moduleMethodMapsWithName:moduleName];
            if (!moduleInfo || ![moduleInfo isKindOfClass:[NSDictionary class]]) {
                break;
            }
            NSString *setting = [WXUtility JSONString:moduleInfo];
            if (setting.length > 0) {
                returnValue->type = ParamsType::BYTEARRAYSTRING;
                const char *pcstr_utf8 = [setting UTF8String];
                returnValue->value.byteArray = generator_bytes_array(pcstr_utf8, setting.length);
            }

        } while (0);
        
        return std::unique_ptr<ValueWithType>(returnValue);
    }
    std::unique_ptr<ValueWithType> IOSSide::CallNativeModule(const char *page_id, const char *module, const char *method, const char *args, int args_length, const char *options, int options_length)
    {
        ValueWithType *returnValue = new ValueWithType();
        memset(returnValue, 0, sizeof(ValueWithType));
        returnValue->type = ParamsType::VOID;
        // should not enter this function
        do {
            NSString *instanceId = NSSTRING(page_id);
            WXSDKInstance *instance = [WXSDKManager instanceForID:instanceId];
            if (!instance) {
                break;
            }
            NSString *moduleName = [NSString stringWithUTF8String:module];
            NSString *methodName = [NSString stringWithUTF8String:method];
            NSArray *newArguments;
            if (args && args_length > 0) {
                NSString *arguments = [NSString stringWithUTF8String:args];
                newArguments = [WXUtility objectFromJSON:arguments];
            }
            LOGD("CallNativeModule:[%s]:[%s]=>%s \n", module, method, args);
            WXModuleMethod *method = [[WXModuleMethod alloc] initWithModuleName:moduleName methodName:methodName arguments:newArguments options:nil instance:instance];
            NSInvocation *invocation = [method invoke];
            if (!invocation) {
                break;
            }
            const char *returnType = [invocation.methodSignature methodReturnType];
            switch (returnType[0] == _C_CONST ? returnType[1] : returnType[0]) {
                case _C_VOID: {
                    // 1.void
                    returnValue->type = ParamsType::VOID;
                    break;
                }
                case _C_ID: {
                    // 2.id
                    void *value;
                    [invocation getReturnValue:&value];
                    id object = (__bridge id)value;
                    if ([object isKindOfClass:[NSString class]]) {
                        returnValue->type = ParamsType::BYTEARRAYSTRING;
                        const char *pcstr_utf8 = [(NSString *)object UTF8String];
                        returnValue->value.byteArray = generator_bytes_array(pcstr_utf8, ((NSString *)object).length);
                    }
                    if ([object isKindOfClass:[NSDictionary class]] || [object isKindOfClass:[NSArray class]]) {
                        NSString *jsonString = [WXUtility JSONString:object];
                        returnValue->type = ParamsType::BYTEARRAYJSONSTRING;
                        returnValue->value.byteArray = generator_bytes_array(jsonString.UTF8String, jsonString.length);
                    }
                    break;
                }
#define WX_MODULE_INT32_VALUE_RET_CASE(ctype, ttype) \
case ctype: {                         \
ttype value;                          \
[invocation getReturnValue:&value];   \
returnValue->type = ParamsType::INT32; \
returnValue->value.int32Value = value; \
break; \
}
#define WX_MODULE_INT64_VALUE_RET_CASE(ctype, ttype) \
case ctype: {                         \
ttype value;                          \
[invocation getReturnValue:&value];   \
returnValue->type = ParamsType::INT64; \
returnValue->value.int64Value = value; \
break; \
}
                // 3.number
                WX_MODULE_INT32_VALUE_RET_CASE(_C_CHR, char)
                WX_MODULE_INT32_VALUE_RET_CASE(_C_UCHR, unsigned char)
                WX_MODULE_INT32_VALUE_RET_CASE(_C_SHT, short)
                WX_MODULE_INT32_VALUE_RET_CASE(_C_USHT, unsigned short)
                WX_MODULE_INT32_VALUE_RET_CASE(_C_INT, int)
                WX_MODULE_INT32_VALUE_RET_CASE(_C_UINT, unsigned int)
                WX_MODULE_INT32_VALUE_RET_CASE(_C_BOOL, BOOL)
                WX_MODULE_INT64_VALUE_RET_CASE(_C_LNG, long)
                WX_MODULE_INT64_VALUE_RET_CASE(_C_ULNG, unsigned long)
                WX_MODULE_INT64_VALUE_RET_CASE(_C_LNG_LNG, long long)
                WX_MODULE_INT64_VALUE_RET_CASE(_C_ULNG_LNG, unsigned long long)
                case _C_FLT:
                {
                    float value;
                    [invocation getReturnValue:&value];
                    returnValue->type = ParamsType::FLOAT;
                    returnValue->value.floatValue = value;
                    break;
                }
                case _C_DBL:
                {
                    double value;
                    [invocation getReturnValue:&value];
                    returnValue->type = ParamsType::DOUBLE;
                    returnValue->value.doubleValue = value;
                    break;
                }
                case _C_STRUCT_B:
                case _C_CHARPTR:
                case _C_PTR:
                case _C_CLASS: {
                    returnValue->type = ParamsType::JSUNDEFINED;
                    break;
                }
            }
            
        } while (0);
        
        return std::unique_ptr<ValueWithType>(returnValue);
    }
        
    void IOSSide::CallNativeComponent(const char *page_id, const char *ref, const char *method,
                                      const char *args, int args_length,
                                      const char *options, int options_length)
    {
        do {
            NSString *instanceId = NSSTRING(page_id);
            WXSDKInstance *instance = [WXSDKManager instanceForID:instanceId];
            if (!instance) {
                break;
            }
            if (!ref || !method) {
                break;
            }
            NSString *componentRef = [NSString stringWithUTF8String:ref];
            NSString *methodName = [NSString stringWithUTF8String:method];
            NSArray *newArguments;
            if (args && args_length > 0) {
                NSString *arguments = [NSString stringWithUTF8String:args];
                newArguments = [WXUtility objectFromJSON:arguments];
            }
            WXComponentMethod *method = [[WXComponentMethod alloc] initWithComponentRef:componentRef methodName:methodName arguments:newArguments instance:instance];
            [method invoke];
            
        } while (0);
    }

    void IOSSide::SetTimeout(const char* callbackID, const char* time)
    {
        // should not enter this function
        assert(false); //!OCLint
    }

    void IOSSide::NativeLog(const char *args)
    {
        // should not enter this function
        do {
            if (!args) {
                break;
            }
            NSArray *newArguments;
            if (args) {
                NSString *arguments = [NSString stringWithUTF8String:args];
                newArguments = [WXUtility objectFromJSON:arguments];
            }
            if (![newArguments isKindOfClass:[NSArray class]] || !newArguments.count) {
                break;
            }
            static NSDictionary *levelMap;
            static dispatch_once_t onceToken;
            dispatch_once(&onceToken, ^{
                levelMap = @{@"__ERROR": @(WXLogFlagError),
                          @"__WARN": @(WXLogFlagWarning),
                          @"__INFO": @(WXLogFlagInfo),
                          @"__DEBUG": @(WXLogFlagDebug),
                          @"__LOG": @(WXLogFlagLog)};
            });
            NSString *levelStr = [newArguments lastObject];
            consoleWithArguments(newArguments, (WXLogFlag)[levelMap[levelStr] integerValue]);
            
        } while (0);
    }
    
    void IOSSide::TriggerVSync(const char* page_id)
    {
        RenderPageBase *page = RenderManager::GetInstance()->GetPage(page_id);
        if (page == nullptr) {
            return;
        }
        
        NSString* ns_instanceId = NSSTRING(page_id);
        WXComponentManager* manager = [WXSDKManager instanceForID:ns_instanceId].componentManager;
        if (!manager.isValid) {
            return;
        }
        [manager startComponentTasks];
    }
        
    int IOSSide::UpdateFinish(const char* page_id, const char* task, int taskLen,
                                   const char* callback, int callbackLen)
    {
        RenderPageBase *page = RenderManager::GetInstance()->GetPage(page_id);
        if (page == nullptr) {
            return -1;
        }
        
        NSString* ns_instanceId = NSSTRING(page_id);
        WXComponentManager* manager = [WXSDKManager instanceForID:ns_instanceId].componentManager;
        if (!manager.isValid) {
            return -1;
        }
        [manager startComponentTasks];
        [manager updateFinish];

        return 0;
    }
        
    int IOSSide::RefreshFinish(const char* pageId, const char *task, const char *callback)
    {
        RenderPageBase *page = RenderManager::GetInstance()->GetPage(pageId);
        if (page == nullptr) {
            return -1;
        }
        
        NSString* ns_instanceId = NSSTRING(pageId);
        WXComponentManager* manager = [WXSDKManager instanceForID:ns_instanceId].componentManager;
        if (!manager.isValid) {
            return -1;
        }
        [manager startComponentTasks];
        [manager refreshFinish];
        
        return 0;
    }
        
    int IOSSide::AddEvent(const char* pageId, const char* ref, const char *event)
    {
        RenderPageBase *page = RenderManager::GetInstance()->GetPage(pageId);
        if (page == nullptr) {
            return -1;
        }
        
        long long startTime = getCurrentTime();
        
        NSString* ns_instanceId = NSSTRING(pageId);
        NSString* ns_ref = NSSTRING(ref);
        NSString* ns_event = NSSTRING(event);
        
#ifdef DEBUG
        WXLogDebug(@"flexLayout -> action: addEvent ref:%@", ns_ref);
#endif
        
        WXComponentManager *manager = [WXSDKManager instanceForID:ns_instanceId].componentManager;
        if (!manager.isValid) {
            return -1;
        }
        [manager startComponentTasks];
        [manager addEvent:ns_event toComponent:ns_ref];

        page->CallBridgeTime(getCurrentTime() - startTime);
        return 0;
    }
        
    int IOSSide::RemoveEvent(const char* pageId, const char* ref, const char *event)
    {
        RenderPageBase *page = RenderManager::GetInstance()->GetPage(pageId);
        if (page == nullptr) {
            return -1;
        }
        
        long long startTime = getCurrentTime();
        
        NSString* ns_instanceId = NSSTRING(pageId);
        NSString* ns_ref = NSSTRING(ref);
        NSString* ns_event = NSSTRING(event);
        
#ifdef DEBUG
        WXLogDebug(@"flexLayout -> action :removeEvent ref:%@", ns_ref);
#endif
        
        WXComponentManager* manager = [WXSDKManager instanceForID:ns_instanceId].componentManager;
        if (!manager.isValid) {
            return -1;
        }
        [manager startComponentTasks];
        [manager removeEvent:ns_event fromComponent:ns_ref];
    
        page->CallBridgeTime(getCurrentTime() - startTime);
        return 0;
    }
        
    int IOSSide::CreateBody(const char* pageId, const char *componentType, const char* ref,
                                     std::map<std::string, std::string> *styles,
                                     std::map<std::string, std::string> *attributes,
                                     std::set<std::string> *events,
                                     const WXCoreMargin &margins,
                                     const WXCorePadding &paddings,
                                     const WXCoreBorderWidth &borders)
    {
        RenderPageBase *page = RenderManager::GetInstance()->GetPage(pageId);
        if (page == nullptr) {
            return -1;
        }
        
        long long startTime = getCurrentTime();
        
        RenderObject* renderObject = page->GetRenderObject(ref);
        
        NSString* ns_instanceId = NSSTRING(pageId);
        NSString* ns_ref = NSSTRING(ref);
        NSString* ns_type = NSSTRING(componentType);
        NSMutableDictionary* ns_styles = NSDICTIONARY(styles);
        NSDictionary* ns_attributes = NSDICTIONARY(attributes);
        NSArray* ns_events = NSARRAY(events);
        
        WXSDKInstance* sdkInstance = [WXSDKManager instanceForID:ns_instanceId];
        MergeBorderWidthValues(ns_styles, borders, false, sdkInstance.pixelScaleFactor);
        
#ifdef DEBUG
        WXLogDebug(@"flexLayout -> action: createBody %@ ref:%@", ns_type, ns_ref);
#endif
        
        WXComponentManager* manager = sdkInstance.componentManager;
        if (!manager.isValid) {
            return -1;
        }
        [manager startComponentTasks];
        [manager createBody:ns_ref type:ns_type styles:ns_styles attributes:ns_attributes events:ns_events renderObject:renderObject];
        
        page->CallBridgeTime(getCurrentTime() - startTime);
        return 0;
    }
        
    int IOSSide::AddElement(const char* pageId, const char *componentType, const char* ref,
                           int &index, const char* parentRef,
                           std::map<std::string, std::string> *styles,
                           std::map<std::string, std::string> *attributes,
                           std::set<std::string> *events,
                           const WXCoreMargin &margins,
                           const WXCorePadding &paddings,
                           const WXCoreBorderWidth &borders,
                           bool willLayout)
    {
        RenderPageBase *page = RenderManager::GetInstance()->GetPage(pageId);
        if (page == nullptr) {
            return -1;
        }
        
        long long startTime = getCurrentTime();
        
        RenderObject* renderObject = page->GetRenderObject(ref);
        
        NSString* ns_instanceId = NSSTRING(pageId);
        NSString* ns_componentType = NSSTRING(componentType);
        NSString* ns_ref = NSSTRING(ref);
        NSString* ns_parentRef = NSSTRING(parentRef);
        NSMutableDictionary* ns_styles = NSDICTIONARY(styles);
        NSDictionary* ns_attributes = NSDICTIONARY(attributes);
        NSArray* ns_events = NSARRAY(events);
        NSInteger ns_index = index;
        
        WXSDKInstance* sdkInstance = [WXSDKManager instanceForID:ns_instanceId];
        MergeBorderWidthValues(ns_styles, borders, false, sdkInstance.pixelScaleFactor);
        
#ifdef DEBUG
        WXLogDebug(@"flexLayout -> action: addElement : %@", ns_componentType);
#endif
        
        WXComponentManager* manager = sdkInstance.componentManager;
        if (!manager.isValid) {
            return -1;
        }
        
        [manager startComponentTasks];
        [manager addComponent:ns_ref type:ns_componentType parentRef:ns_parentRef styles:ns_styles attributes:ns_attributes events:ns_events index:ns_index renderObject:renderObject];

        page->CallBridgeTime(getCurrentTime() - startTime);
        return 0;
    }
    
    int IOSSide::AddChildToRichtext(const char* pageId, const char *nodeType, const char* ref,
                            const char* parentRef, const char* richtextRef,
                            std::map<std::string, std::string> *styles,
                            std::map<std::string, std::string> *attributes)
    {
        RenderPageBase *page = RenderManager::GetInstance()->GetPage(pageId);
        if (page == nullptr) {
            return -1;
        }
        NSString* ns_richtextRef = NSSTRING(richtextRef);
        NSString* ns_instanceId = NSSTRING(pageId);
        NSString* ns_nodeType = NSSTRING(nodeType);
        NSString* ns_ref = NSSTRING(ref);
        NSString* ns_parentRef = NSSTRING(parentRef);
        NSMutableDictionary* ns_styles = NSDICTIONARY(styles);
        NSDictionary* ns_attributes = NSDICTIONARY(attributes);

        WXSDKInstance* sdkInstance = [WXSDKManager instanceForID:ns_instanceId];
        WXComponentManager* manager = sdkInstance.componentManager;
        if (!manager.isValid) {
            return -1;
        }

        WXRichText* richtext = (WXRichText*)[manager componentForRef:ns_richtextRef];
        [richtext addChildNode:ns_nodeType ref:ns_ref styles:ns_styles attributes:ns_attributes toSuperNodeRef:ns_parentRef];
        return 0;
    }

    int IOSSide::Layout(const char* pageId, const char* ref,
                       float top, float bottom, float left, float right,
                       float height, float width, bool isRTL, int index)
    {
        RenderPageBase *page = RenderManager::GetInstance()->GetPage(pageId);
        if (page == nullptr) {
            return -1;
        }
        
        long long startTime = getCurrentTime();
        
        RenderObject* renderObject = page->GetRenderObject(ref);
        if (renderObject->getContext() == nullptr) {
            return -1;
        }
        WXComponent* component = (__bridge WXComponent *)(renderObject->getContext());
        NSString* ns_instanceId = NSSTRING(pageId);
        
        WXComponentManager* manager = [WXSDKManager instanceForID:ns_instanceId].componentManager;
        if (!manager.isValid) {
            return -1;
        }
        CGRect frame = CGRectMake(isnan(WXCeilPixelValue(left))?0:WXCeilPixelValue(left),
                                  isnan(WXCeilPixelValue(top))?0:WXCeilPixelValue(top),
                                  isnan(WXCeilPixelValue(width))?0:WXCeilPixelValue(width),
                                  isnan(WXCeilPixelValue(height))?0:WXCeilPixelValue(height));
        [manager layoutComponent:component frame:frame isRTL:isRTL innerMainSize:renderObject->getLargestMainSize()];

        page->CallBridgeTime(getCurrentTime() - startTime);
        return 0;
    }
    
    void IOSSide::InvokeLayoutPlatform(const char* page_id, long render_ptr)
    {
        RenderPageBase *page = RenderManager::GetInstance()->GetPage(page_id);
        if (page == nullptr) {
            return;
        }
        
        long long startTime = getCurrentTime();
        
        RenderObject* renderObject = reinterpret_cast<RenderObject*>(render_ptr);
        if (renderObject->getContext() == nullptr) {
            return;
        }
        WXComponent* component = (__bridge WXComponent *)(renderObject->getContext());
        NSString* ns_instanceId = NSSTRING(page_id);
        
        WXComponentManager* manager = [WXSDKManager instanceForID:ns_instanceId].componentManager;
        if (!manager.isValid) {
            return;
        }
        
        [manager layoutComponent:component];

        page->CallBridgeTime(getCurrentTime() - startTime);
    }
    
    int IOSSide::UpdateRichtextStyle(const char* pageId, const char* ref,
                             std::vector<std::pair<std::string, std::string>> *style,
                             const char* parent_ref, const char* richtext_ref)
    {
        RenderPageBase *page = RenderManager::GetInstance()->GetPage(pageId);
        if (page == nullptr) {
            return -1;
        }

        NSString* ns_instanceId = NSSTRING(pageId);
        NSString* ns_ref = NSSTRING(ref);
        NSString* ns_richtextRef = NSSTRING(richtext_ref);
        NSString* ns_parentRef = NSSTRING(parent_ref);
        NSMutableDictionary* ns_style = NSDICTIONARY(style);

        WXSDKInstance* sdkInstance = [WXSDKManager instanceForID:ns_instanceId];
        if (!sdkInstance) {
            return -1;
        }
        WXComponentManager* manager = sdkInstance.componentManager;
        if (!manager.isValid) {
            return -1;
        }

        WXRichText* richtext = (WXRichText*)[manager componentForRef:ns_richtextRef];
        [richtext updateChildNodeStyles:ns_style ref:ns_ref parentRef:ns_parentRef];
        return 0;
    }

    int IOSSide::UpdateStyle(const char* pageId, const char* ref,
                            std::vector<std::pair<std::string, std::string>> *style,
                            std::vector<std::pair<std::string, std::string>> *margin,
                            std::vector<std::pair<std::string, std::string>> *padding,
                            std::vector<std::pair<std::string, std::string>> *border)
    {
        RenderPageBase *page = RenderManager::GetInstance()->GetPage(pageId);
        if (page == nullptr) {
            return -1;
        }
        
        long long startTime = getCurrentTime();
        
        NSString* ns_instanceId = NSSTRING(pageId);
        NSString* ns_ref = NSSTRING(ref);
        NSMutableDictionary* ns_style = NSDICTIONARY(style);
        
        WXSDKInstance* sdkInstance = [WXSDKManager instanceForID:ns_instanceId];
        MergeBorderWidthValues(ns_style, border, sdkInstance.pixelScaleFactor);
        
#ifdef DEBUG
        WXLogDebug(@"flexLayout -> action: updateStyles ref:%@, styles:%@", ns_ref, ns_style);
#endif
        
        WXComponentManager* manager = sdkInstance.componentManager;
        if (!manager.isValid) {
            return -1;
        }
        
        [manager startComponentTasks];
        [manager updateStyles:ns_style forComponent:ns_ref];
        
        page->CallBridgeTime(getCurrentTime() - startTime);
        return 0;
    }
        
    int IOSSide::UpdateAttr(const char* pageId, const char* ref,
                           std::vector<std::pair<std::string, std::string>> *attrs)
    {
        if (attrs == nullptr) {
            return 0;
        }
        if (attrs->size() == 0) {
            return 0;
        }
        
        RenderPageBase *page = RenderManager::GetInstance()->GetPage(pageId);
        if (page == nullptr) {
            return -1;
        }
        
        long long startTime = getCurrentTime();
        
        NSString* ns_instanceId = NSSTRING(pageId);
        NSString* ns_ref = NSSTRING(ref);
        NSDictionary* ns_attributes = NSDICTIONARY(attrs);
        
#ifdef DEBUG
        WXLogDebug(@"flexLayout -> action: updateAttrs ref:%@, attr:%@", ns_ref, ns_attributes);
#endif
        
        WXComponentManager* manager = [WXSDKManager instanceForID:ns_instanceId].componentManager;
        if (!manager.isValid) {
            return -1;
        }
        [manager startComponentTasks];
        [manager updateAttributes:ns_attributes forComponent:ns_ref];

        page->CallBridgeTime(getCurrentTime() - startTime);
        return 0;
    }

    int IOSSide::UpdateRichtextChildAttr(const char* pageId, const char* ref,
                            std::vector<std::pair<std::string, std::string>> *attrs, const char* parent_ref, const char* richtext_ref)
    {
        RenderPageBase *page = RenderManager::GetInstance()->GetPage(pageId);
        if (page == nullptr) {
            return -1;
        }
        if (attrs == nullptr) {
            return 0;
        }
        if (attrs->size() == 0) {
            return 0;
        }

        NSString* ns_instanceId = NSSTRING(pageId);
        NSString* ns_ref = NSSTRING(ref);
        NSString* ns_parentRef = NSSTRING(parent_ref);
        NSString* ns_richtextRef = NSSTRING(richtext_ref);
        NSDictionary* ns_attributes = NSDICTIONARY(attrs);
        WXSDKInstance* sdkInstance = [WXSDKManager instanceForID:ns_instanceId];
        if (!sdkInstance) {
            return -1;
        }
        WXComponentManager* manager = sdkInstance.componentManager;
        if (!manager.isValid) {
            return -1;
        }

        WXRichText* richtext = (WXRichText*)[manager componentForRef:ns_richtextRef];
        [richtext updateChildNodeAttributes:ns_attributes ref:ns_ref parentRef:ns_parentRef];
        return 0;
    }
        
    int IOSSide::CreateFinish(const char* pageId)
    {
        RenderPageBase *page = RenderManager::GetInstance()->GetPage(pageId);
        
        long long startTime = getCurrentTime();
        
        NSString* ns_instanceId = NSSTRING(pageId);

#ifdef DEBUG
        WXLogDebug(@"flexLayout -> action: createFinish :%@", ns_instanceId);
#endif
        
        WXComponentManager* manager = [WXSDKManager instanceForID:ns_instanceId].componentManager;
        if (!manager.isValid) {
            return -1;
        }
        [manager startComponentTasks];
        [manager createFinish];

        if (page) {
            page->CallBridgeTime(getCurrentTime() - startTime);
        }
        return 0;
    }
    
    int IOSSide::RenderSuccess(const char* pageId)
    {
        RenderPageBase *page = RenderManager::GetInstance()->GetPage(pageId);
        
        long long startTime = getCurrentTime();
        
        NSString* ns_instanceId = NSSTRING(pageId);
        
#ifdef DEBUG
        WXLogDebug(@"flexLayout -> action: renderFinish :%@", ns_instanceId);
#endif
        
        WXComponentManager* manager = [WXSDKManager instanceForID:ns_instanceId].componentManager;
        if (!manager.isValid) {
            return -1;
        }
        [manager startComponentTasks];
        [manager renderFinish];
        
        if (page) {
            page->CallBridgeTime(getCurrentTime() - startTime);
        }
        return 0;
    }

    int IOSSide::RemoveChildFromRichtext(const char* pageId, const char* ref, const char* parent_ref, const char* richtext_ref) {
        RenderPageBase *page = RenderManager::GetInstance()->GetPage(pageId);
        if (page == nullptr) {
            return -1;
        }
        
        NSString* ns_instanceId = NSSTRING(pageId);
        NSString* ns_richtextRef = NSSTRING(richtext_ref);
        NSString* ns_ref = NSSTRING(ref);
        NSString* ns_parentRef = NSSTRING(parent_ref);

        WXSDKInstance* sdkInstance = [WXSDKManager instanceForID:ns_instanceId];
        WXComponentManager* manager = sdkInstance.componentManager;
        if (!manager.isValid) {
            return -1;
        }

        WXRichText* richtext = (WXRichText*)[manager componentForRef:ns_richtextRef];
        [richtext removeChildNode:ns_ref superNodeRef:ns_parentRef];
        return 0;
    }
    int IOSSide::RemoveElement(const char* pageId, const char* ref)
    {
        RenderPageBase *page = RenderManager::GetInstance()->GetPage(pageId);
        if (page == nullptr) {
            return -1;
        }
        
        long long startTime = getCurrentTime();
        
        NSString* ns_instanceId = NSSTRING(pageId);
        NSString* ns_ref = NSSTRING(ref);
        
#ifdef DEBUG
        WXLogDebug(@"flexLayout -> action: removeElement ref:%@", ns_ref);
#endif
        
        WXComponentManager* manager = [WXSDKManager instanceForID:ns_instanceId].componentManager;
        if (!manager.isValid) {
            return -1;
        }
        
        [manager startComponentTasks];
        [manager removeComponent:ns_ref];
        
        page->CallBridgeTime(getCurrentTime() - startTime);
        return 0;
    }
        
    int IOSSide::MoveElement(const char* pageId, const char* ref, const char* parentRef, int index)
    {
        RenderPageBase *page = RenderManager::GetInstance()->GetPage(pageId);
        if (page == nullptr) {
            return -1;
        }
        
        long long startTime = getCurrentTime();
        
        NSString* ns_instanceId = NSSTRING(pageId);
        NSString* ns_ref = NSSTRING(ref);
        NSString* ns_parentRef = NSSTRING(parentRef);
        NSInteger ns_index = index;
        
#ifdef DEBUG
        WXLogDebug(@"flexLayout -> action: moveElement, ref:%@ to ref:%@", ns_ref, ns_parentRef);
#endif
        
        WXComponentManager* manager = [WXSDKManager instanceForID:ns_instanceId].componentManager;
        if (!manager.isValid) {
            return -1;
        }
        
        [manager startComponentTasks];
        [manager moveComponent:ns_ref toSuper:ns_parentRef atIndex:ns_index];
        
        page->CallBridgeTime(getCurrentTime() - startTime);
        return 0;
    }
        
    int IOSSide::AppendTreeCreateFinish(const char* pageId, const char* ref)
    {
        RenderPageBase *page = RenderManager::GetInstance()->GetPage(pageId);
        if (page == nullptr) {
            return -1;
        }
        
        long long startTime = getCurrentTime();
        
        NSString* ns_instanceId = NSSTRING(pageId);
        NSString* ns_ref = NSSTRING(ref);

        WXComponentManager* manager = [WXSDKManager instanceForID:ns_instanceId].componentManager;
        if (!manager.isValid) {
            return -1;
        }
        [manager startComponentTasks];
        [manager appendTreeCreateFinish:ns_ref];
        
        page->CallBridgeTime(getCurrentTime() - startTime);
        return 0;
    }
    
    int IOSSide::HasTransitionPros(const char* pageId, const char* ref,
                              std::vector<std::pair<std::string, std::string>> *style)
    {
        RenderPageBase *page = RenderManager::GetInstance()->GetPage(pageId);
        if (page == nullptr) {
            return -1;
        }
        
        long long startTime = getCurrentTime();
        
        NSString* ns_instanceId = NSSTRING(pageId);
        NSString* ns_ref = NSSTRING(ref);
        
        WXComponentManager* manager = [WXSDKManager instanceForID:ns_instanceId].componentManager;
        if (!manager.isValid) {
            return -1;
        }
        
        // if transition is none, return directly, avoiding convert style
        if ([manager isTransitionNoneOfComponent:ns_ref]) {
            return 0;
        }
        
        int result = [manager hasTransitionPropertyInStyles:NSDICTIONARY(style) forComponent:ns_ref] ? 1 : 0;
        
        page->CallBridgeTime(getCurrentTime() - startTime);
        return result;
    }

    void IOSSide::PostTaskOnComponentThread(const weex::base::Closure closure) {
        WXPerformBlockOnComponentThread(^{
            closure();
        });
    }

#pragma mark - Layout Impl
    
    WXCoreSize WXCoreMeasureFunctionBridge::Measure(const char* page_id, long render_ptr, float width, MeasureMode widthMeasureMode, float height, MeasureMode heightMeasureMode)
    {
        // should not enter this function
        assert(false); //!OCLint
    }
    
    void WXCoreMeasureFunctionBridge::LayoutBefore(const char* page_id, long render_ptr)
    {
        
    }
    
    void WXCoreMeasureFunctionBridge::LayoutAfter(const char* page_id, long render_ptr, float width, float height)
    {
        
    }
    
#pragma mark - Log Bridge
    
    class LogBridgeIOS: public weex::base::LogBase {
    public:
        virtual bool log(LogLevel level, const char* tag, const char* file, unsigned long line, const char* log) override {
#ifdef DEBUG
            switch (level) {
                case LogLevel::Error:
                    printf("<%s:Error|%s:%lu> %s\n", tag, file, line, log);
                    break;
                case LogLevel::Warn:
                    printf("<%s:Warn|%s:%lu> %s\n", tag, file, line, log);
                    break;
                case LogLevel::Info:
                    printf("<%s:Info|%s:%lu> %s\n", tag, file, line, log);
                    break;
                case LogLevel::Debug:
                    printf("<%s:Debug|%s:%lu> %s\n", tag, file, line, log);
                    break;
                default:
                    break;
            }
#else
            WXLogFlag wxLogLevel;
            switch (level) {
                case LogLevel::Error:
                    wxLogLevel = WXLogFlagError;
                    break;
                case LogLevel::Warn:
                    wxLogLevel = WXLogFlagWarning;
                    break;
                case LogLevel::Info:
                    wxLogLevel = WXLogFlagInfo;
                    break;
                default:
                    wxLogLevel = WXLogFlagDebug;
                    break;
            }
            
            [WXLog devLog:wxLogLevel file:file line:line format:@"<%s> %s", tag, log];
#endif
            return true;
        }
    };
}

@interface WXCustomPageBridge()
{
    std::mutex _customPageLock;
    std::map<std::string, WeexCore::RenderPageCustom*> _customPages;
    
    WeexCore::RenderPageCustom* _lastPage;
}

@end

@implementation WXCustomPageBridge

+ (instancetype)sharedInstance
{
    static dispatch_once_t onceToken;
    static WXCustomPageBridge* instance;
    dispatch_once(&onceToken, ^{
        instance = [[WXCustomPageBridge alloc] init];
    });
    return instance;
}

+ (BOOL)isCustomPage:(NSString*)pageId
{
    return [pageId integerValue] % 2 != 0;
}

+ (NSSet<NSString*>*)getAvailableCustomRenderTypes
{
    NSMutableSet<NSString*>* result = [[NSMutableSet alloc] init];
    for (const std::string& s : WeexCore::RenderTargetManager::sharedInstance()->getAvailableTargetNames()) {
        [result addObject:NSSTRING(s.c_str())];
    }
    return result;
}

+ (UIView*)createPageRootView:(NSString*)pageId pageType:(NSString*)pageType frame:(CGRect)frame
{
    auto target = WeexCore::RenderTargetManager::sharedInstance()->getRenderTarget([pageType UTF8String]?:"");
    if (target) {
        return (__bridge UIView*)((void*)(target->createRootView([pageId UTF8String]?:"", frame.origin.x, frame.origin.y, frame.size.width, frame.size.height)));
    }
    return nil;
}

+ (void)parseRenderObject:(NSDictionary *)data
                parentRef:(const std::string&)parentRef
                    index:(int)index
                genObject:(void(^)(const std::string& ref,
                                   const std::string& type,
                                   const std::string& parentRef,
                                   std::map<std::string, std::string>* styles,
                                   std::map<std::string, std::string>* attrs,
                                   std::set<std::string>* events,
                                   int index))onGenObject
{
    const char* type = [data[@"type"] UTF8String];
    const char* ref = [data[@"ref"] UTF8String];
    if (type != nullptr && ref != nullptr) {
        std::map<std::string, std::string>* styles = new std::map<std::string, std::string>();
        std::map<std::string, std::string>* attrs = new std::map<std::string, std::string>();
        std::set<std::string>* events = new std::set<std::string>();
        
        [data[@"attr"] enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            ConvertToCString(obj, ^(const char * value) {
                if (value != nullptr) {
                    (*attrs)[[key UTF8String]] = value;
                }
            });
        }];
        
        [data[@"style"] enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            ConvertToCString(obj, ^(const char * value) {
                if (value != nullptr) {
                    (*styles)[[key UTF8String]] = value;
                }
            });
        }];
        
        for (id obj in data[@"event"]) {
            ConvertToCString(obj, ^(const char * value) {
                if (value != nullptr) {
                    events->insert(value);
                }
            });
        }
        
        std::string thisRef = ref;
        std::string thisType = type;
        onGenObject(thisRef, thisType, parentRef, styles, attrs, events, index);
        
        // parse children
        int childIndex = 0;
        for (NSDictionary* obj in data[@"children"]) {
            [self parseRenderObject:obj parentRef:thisRef index:childIndex ++ genObject:onGenObject];
        }
    }
}

+ (std::vector<std::pair<std::string, std::string>>*)parseMapValuePairs:(NSDictionary *)data
{
    std::vector<std::pair<std::string, std::string>>* result = new std::vector<std::pair<std::string, std::string>>();
    [data enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        ConvertToCString(obj, ^(const char * value) {
            if (value != nullptr) {
                result->emplace_back([key UTF8String], value);
            }
        });
    }];
    return result;
}

- (WeexCore::RenderPageCustom*)getPage:(NSString*)pageId
{
    std::lock_guard<std::mutex> lockGuard(_customPageLock);
    std::string sId = [pageId UTF8String] ?: "";
    if (_lastPage && _lastPage->page_id() == sId) {
        // avoid a map search
        return _lastPage;
    }
    auto findPage = _customPages.find([pageId UTF8String] ?: "");
    _lastPage = findPage == _customPages.end() ? nullptr : findPage->second;
    return _lastPage;
}

- (void)invalidatePage:(NSString*)pageId
{
    std::lock_guard<std::mutex> lockGuard(_customPageLock);
    auto findPage = _customPages.find([pageId UTF8String] ?: "");
    if (findPage != _customPages.end()) {
        findPage->second->Invalidate();
    }
}

- (void)removePage:(NSString*)pageId
{
    RenderPageCustom* thePage = nullptr;
    {
        std::lock_guard<std::mutex> lockGuard(_customPageLock);
        auto findPage = _customPages.find([pageId UTF8String] ?: "");
        if (findPage != _customPages.end()) {
            thePage = findPage->second;
            _customPages.erase(findPage);
        }
    }
    
    if (thePage) {
        thePage->OnRenderPageClose();
        delete thePage;
        _lastPage = nullptr;
    }
}

- (void)callCreateBody:(NSString*)pageId data:(NSDictionary*)data
{
    using namespace WeexCore;
    
    WXSDKInstance* sdkInstance = [WXSDKManager instanceForID:pageId];
    WXComponentManager* manager = sdkInstance.componentManager;
    if (!manager.isValid) {
        return;
    }
    
    std::string sId = [pageId UTF8String] ?: "";
    if (sId.empty()) {
        return;
    }
    
    auto pageArgs = RenderManager::GetInstance()->removePageArguments(sId);
    RenderPageCustom::PageOptions options;
    
    options.is_round_off = false;
    options.view_scale = 1;
    auto value = WXCoreEnvironment::getInstance()->GetOption("pixel_scale");
    if (value != "") {
        options.view_scale = strtof(value.c_str(), NULL);
    }
    
    auto findViewPort = pageArgs.find("viewportwidth");
    if (findViewPort != pageArgs.end()) {
        options.viewport_width = strtof(findViewPort->second.c_str(), nullptr);
    }
    else {
        options.viewport_width = kDefaultViewPortWidth;
    }
    
    auto findDeviceWidth = pageArgs.find("devicewidth");
    if (findDeviceWidth != pageArgs.end()) {
        options.device_width = strtof(findDeviceWidth->second.c_str(), nullptr);
    }
    else {
        /* For iOS DeviceWidth stored by WeexCore is in UIKit view system coordinate(iPhone6 is 375).
         So we must provide heron with the pixel device width here. */
        options.device_width = WXCoreEnvironment::getInstance()->DeviceWidth() * options.view_scale;
    }
    
    std::swap(options.args, pageArgs);
    
    RenderPageCustom* page = new RenderPageCustom(sId, "heron", options);
    
    {
        std::lock_guard<std::mutex> lockGuard(_customPageLock);
        _customPages[sId] = page;
    }
    
    SetConvertCurrentPage(pageId);
    [WXCustomPageBridge parseRenderObject:data parentRef:"" index:0 genObject:^(const std::string &ref, const std::string &type, const std::string &parentRef, std::map<std::string, std::string> *styles, std::map<std::string, std::string> *attrs, std::set<std::string> *events, int index) {
        if (parentRef.empty()) {
            // is root body
            page->CreateBody(ref, type, styles, attrs, events);
        }
        else {
            page->AddRenderObject(ref, type, parentRef, index, styles, attrs, events);
        }
    }];
}

- (void)callAddElement:(NSString*)pageId parentRef:(NSString*)parentRef data:(NSDictionary*)data index:(int)index
{
    RenderPageCustom* page = [self getPage:pageId];
    if (page && page->IsValid()) {
        [WXCustomPageBridge parseRenderObject:data parentRef:[parentRef UTF8String] ?: "" index:index genObject:^(const std::string &ref, const std::string &type, const std::string &parentRef, std::map<std::string, std::string> *styles, std::map<std::string, std::string> *attrs, std::set<std::string> *events, int index) {
            page->AddRenderObject(ref, type, parentRef, index, styles, attrs, events);
        }];
    }
}

- (void)callRemoveElement:(NSString*)pageId ref:(NSString*)ref
{
    RenderPageCustom* page = [self getPage:pageId];
    if (page && page->IsValid()) {
        page->RemoveRenderObject([ref UTF8String] ?: "");
    }
}

- (void)callMoveElement:(NSString*)pageId ref:(NSString*)ref parentRef:(NSString*)parentRef index:(int)index
{
    RenderPageCustom* page = [self getPage:pageId];
    if (page && page->IsValid()) {
        page->MoveRenderObject([ref UTF8String] ?: "", [parentRef UTF8String] ?: "", index);
    }
}

- (void)callUpdateAttrs:(NSString*)pageId ref:(NSString*)ref data:(NSDictionary*)data
{
    RenderPageCustom* page = [self getPage:pageId];
    if (page && page->IsValid()) {
        SetConvertCurrentPage(pageId);
        page->UpdateAttr([ref UTF8String] ?: "", [WXCustomPageBridge parseMapValuePairs:data]);
    }
}

- (void)callUpdateStyle:(NSString*)pageId ref:(NSString*)ref data:(NSDictionary*)data
{
    RenderPageCustom* page = [self getPage:pageId];
    if (page && page->IsValid()) {
        SetConvertCurrentPage(pageId);
        page->UpdateStyle([ref UTF8String] ?: "", [WXCustomPageBridge parseMapValuePairs:data]);
    }
}

- (void)callAddEvent:(NSString*)pageId ref:(NSString*)ref event:(NSString*)event
{
    RenderPageCustom* page = [self getPage:pageId];
    if (page && page->IsValid()) {
        page->AddEvent([ref UTF8String] ?: "", [event UTF8String] ?: "");
    }
}

- (void)callRemoveEvent:(NSString*)pageId ref:(NSString*)ref event:(NSString*)event
{
    RenderPageCustom* page = [self getPage:pageId];
    if (page && page->IsValid()) {
        page->RemoveEvent([ref UTF8String] ?: "", [event UTF8String] ?: "");
    }
}

- (void)callCreateFinish:(NSString*)pageId
{
    WXPerformBlockOnComponentThread(^{
        RenderPageCustom* page = [self getPage:pageId];
        if (page && page->IsValid()) {
            page->CreateFinish();
        }
    });
}

- (void)callRefreshFinish:(NSString*)pageId
{
    // TODO, this may not be correct, for heron may also need to implement refresh finish.
    WeexCore::WeexCoreManager::Instance()->script_bridge()->core_side()->RefreshFinish([pageId UTF8String] ?: "", nullptr, nullptr);
}

- (void)callUpdateFinish:(NSString*)pageId
{
    // TODO, this may not be correct, for heron may also need to implement update finish.
    WeexCore::WeexCoreManager::Instance()->script_bridge()->core_side()->UpdateFinish([pageId UTF8String] ?: "", nullptr, 0, nullptr, 0);
}

- (BOOL)forwardCallNativeModuleToCustomPage:(NSString*)pageId
                                 moduleName:(NSString*)moduleName methodName:(NSString*)methodName
                                  arguments:(NSArray*)arguments options:(NSDictionary*)options
                                returnValue:(id*)returnValue
{
    using namespace WeexCore;
    
    RenderPageCustom* page = [self getPage:pageId];
    if (page && page->IsValid()) {
        RenderTarget* target = page->GetRenderTarget();
        if (target && target->shouldHandleModuleMethod([moduleName UTF8String] ?: "", [methodName UTF8String] ?: "")) {
            __block const char* seralizedArguments = nullptr;
            __block const char* seralizedOptions = nullptr;
            SetConvertCurrentPage(pageId);
            ConvertToCString(arguments, ^(const char * value) {
                if (value != nullptr) {
                    seralizedArguments = strdup(value);
                }
            });
            ConvertToCString(options, ^(const char * value) {
                if (value != nullptr) {
                    seralizedOptions = strdup(value);
                }
            });
            
            bool handled = false;
            std::unique_ptr<ValueWithType> result = target->callNativeModule([pageId UTF8String] ?: "", [moduleName UTF8String] ?: "", [methodName UTF8String] ?: "", seralizedArguments ?: "", seralizedArguments ? (int)(strlen(seralizedArguments)) : 0, seralizedOptions ?: "", seralizedOptions ? (int)(strlen(seralizedOptions)) : 0, handled);
            
            if (seralizedArguments) {
                free((void*)seralizedArguments);
            }
            if (seralizedOptions) {
                free((void*)seralizedOptions);
            }
            
            if (handled && result) {
                switch (result->type) {
                    case ParamsType::INT32:
                        *returnValue = @(result->value.int32Value);
                        break;
                    case ParamsType::INT64:
                        *returnValue = @(result->value.int64Value);
                        break;
                    case ParamsType::FLOAT:
                        *returnValue = @(result->value.floatValue);
                        break;
                    case ParamsType::DOUBLE:
                        *returnValue = @(result->value.doubleValue);
                        break;
                    case ParamsType::JSONSTRING:
                    {
                        NSString* s = [NSString stringWithCharacters:(const unichar *)(result->value.string->content) length:result->value.string->length];
                        free(result->value.string);
                        
                        @try {
                            NSError* error = nil;
                            id jsonObj = [NSJSONSerialization JSONObjectWithData:[s dataUsingEncoding:NSUTF8StringEncoding]
                                                                         options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves
                                                                           error:&error];
                            
                            if (jsonObj == nil) {
                                WXLogError(@"%@", error);
                                WXAssert(NO, @"Fail to convert json to object. %@", error);
                            }
                            else {
                                *returnValue = jsonObj;
                            }
                        } @catch (NSException *exception) {
                            WXLogError(@"%@", exception);
                            WXAssert(NO, @"Fail to convert json to object. %@", exception);
                        }
                    }
                        break;
                    case ParamsType::STRING:
                        *returnValue = [NSString stringWithCharacters:(const unichar *)(result->value.string->content) length:result->value.string->length];
                        free(result->value.string);
                        break;
                    default:
                        *returnValue = nil;
                        break;
                }
                return YES;
            }
        }
    }
    
    return NO;
}

- (void)forwardCallComponentToCustomPage:(NSString*)pageId
                                     ref:(NSString*)ref
                              methodName:(NSString*)methodName
                               arguments:(NSArray*)arguments
                                 options:(NSDictionary*)options
{
    using namespace WeexCore;
    
    RenderPageCustom* page = [self getPage:pageId];
    if (page && page->IsValid()) {
        RenderTarget* target = page->GetRenderTarget();
        if (target) {
            __block const char* seralizedArguments = nullptr;
            __block const char* seralizedOptions = nullptr;
            SetConvertCurrentPage(pageId);
            ConvertToCString(arguments, ^(const char * value) {
                if (value != nullptr) {
                    seralizedArguments = strdup(value);
                }
            });
            ConvertToCString(options, ^(const char * value) {
                if (value != nullptr) {
                    seralizedOptions = strdup(value);
                }
            });
            
            target->callNativeComponent([pageId UTF8String] ?: "", [ref UTF8String] ?: "", [methodName UTF8String] ?: "", seralizedArguments ?: "", seralizedArguments ? (int)(strlen(seralizedArguments)) : 0, seralizedOptions ?: "", seralizedOptions ? (int)(strlen(seralizedOptions)) : 0);
            
            if (seralizedArguments) {
                free((void*)seralizedArguments);
            }
            if (seralizedOptions) {
                free((void*)seralizedOptions);
            }
        }
    }
}

@end

@implementation WXCoreBridge

static WeexCore::PlatformBridge* platformBridge = nullptr;
static WeexCore::ScriptBridge* jsBridge = nullptr;

+ (void)install
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        WeexCore::WXCoreEnvironment* env = WeexCore::WXCoreEnvironment::getInstance();
        env->SetPlatform(OS_iOS);
        
        /* For historical reason, layout in weexcore and layout result are in iOS UIView system unit.
         So we pass 'scale' as 1 to affect nothing.
         */
        env->AddOption("scale", "1");
        env->AddOption("pixel_scale", std::to_string([[UIScreen mainScreen] scale]));
        
        // Here we initialize weex device width and height using portrait by default.
        CGSize screenSize = [UIScreen mainScreen].bounds.size;
        CGFloat w = MIN(screenSize.width, screenSize.height);
        CGFloat h = MAX(screenSize.width, screenSize.height);
        env->SetDeviceWidth(std::to_string(w));
        env->SetDeviceHeight(std::to_string(h));
        env->AddOption("screen_width_pixels", std::to_string(w));
        env->AddOption("screen_height_pixels", std::to_string(h));
        
        weex::base::LogImplement::getLog()->setLogImplement(new WeexCore::LogBridgeIOS());
        
#ifdef DEBUG
        weex::base::LogImplement::getLog()->setDebugMode(true);
#else
        weex::base::LogImplement::getLog()->setDebugMode(false);
#endif
        
        platformBridge = new WeexCore::PlatformBridge();
        platformBridge->set_platform_side(new WeexCore::IOSSide());
        platformBridge->set_core_side(new WeexCore::CoreSideInPlatform());
        WeexCore::WeexCoreManager::Instance()->set_platform_bridge(platformBridge);
        
        jsBridge = new WeexCore::ScriptBridge();
        jsBridge->set_core_side(new WeexCore::CoreSideInScript());
        WeexCore::WeexCoreManager::Instance()->set_script_bridge(jsBridge);
        
        WeexCore::WeexCoreManager::Instance()->set_measure_function_adapter(new WeexCore::WXCoreMeasureFunctionBridge());

        [[WXSDKManager bridgeMgr] checkJSThread];
    });
}

+ (void)registerComponentAffineType:(NSString *)type asType:(NSString *)baseType
{
    WeexCore::RenderCreator::GetInstance()->RegisterAffineType([type UTF8String] ?: "", [baseType UTF8String] ?: "");
}

+ (BOOL)isComponentAffineType:(NSString *)type asType:(NSString *)baseType
{
    return WeexCore::RenderCreator::GetInstance()->IsAffineType([type UTF8String] ?: "", [baseType UTF8String] ?: "");
}

+ (void)setDefaultDimensionIntoRoot:(NSString*)pageId width:(CGFloat)width height:(CGFloat)height
                 isWidthWrapContent:(BOOL)isWidthWrapContent
                isHeightWrapContent:(BOOL)isHeightWrapContent
{
    if (platformBridge) {
        if (width == 0 && !isWidthWrapContent) {
            return;
        }
        
        if (height == 0 && !isHeightWrapContent) {
            return;
        }
        
        platformBridge->core_side()->SetDefaultHeightAndWidthIntoRootDom([pageId UTF8String] ?: "", (float)width, (float)height, (bool)isWidthWrapContent, (bool)isHeightWrapContent);
    }
}

+ (void)setDeviceSize:(CGSize)size
{
    [WXCoreBridge install];
    WeexCore::WXCoreEnvironment* env = WeexCore::WXCoreEnvironment::getInstance();
    env->SetDeviceWidth(std::to_string(size.width));
    env->SetDeviceHeight(std::to_string(size.height));
}

+ (CGSize)getDeviceSize
{
    [WXCoreBridge install];
    WeexCore::WXCoreEnvironment* env = WeexCore::WXCoreEnvironment::getInstance();
    return CGSizeMake(env->DeviceWidth(), env->DeviceHeight());
}

+ (void)setViewportWidth:(NSString*)pageId width:(CGFloat)width
{
    [WXCoreBridge install];
    if (platformBridge) {
        platformBridge->core_side()->SetViewPortWidth([pageId UTF8String] ?: "", (float)width);
    }
}

+ (void)setPageRequired:(NSString *)pageId width:(CGFloat)width height:(CGFloat)height
{
    [WXCoreBridge install];
    if (platformBridge) {
        platformBridge->core_side()->SetDeviceDisplayOfPage([pageId UTF8String] ?: "", (float)width, (float)height);
    }
}

+ (void)layoutPage:(NSString*)pageId forced:(BOOL)forced
{
    if (platformBridge) {
        const char* page = [pageId UTF8String] ?: "";
        if (forced) {
            platformBridge->core_side()->SetPageDirty(page);
        }
        
        if (platformBridge->core_side()->NotifyLayout(page)) {
            platformBridge->core_side()->ForceLayout(page);
        }
    }
}

+ (double)getLayoutTime:(NSString*)pageId {
    if (platformBridge) {
        const char* page = [pageId UTF8String] ?: "";
        return platformBridge->core_side()->GetLayoutTime(page);
    }
    return 0;
}

+ (void)closePage:(NSString*)pageId
{
    if (platformBridge) {
        platformBridge->core_side()->DestroyInstance([pageId UTF8String]);
        platformBridge->core_side()->OnInstanceClose([pageId UTF8String] ?: "");
    }
}

+ (BOOL)reloadPageLayout:(NSString*)pageId
{
    if (platformBridge) {
        return platformBridge->core_side()->RelayoutUsingRawCssStyles([pageId UTF8String] ?: "");
    }
    return false;
}

+ (void)_traverseTree:(WeexCore::RenderObject *)render index:(int)index pageId:(const char *)pageId
{
    using namespace WeexCore;
    if (render == nullptr) return;

    if (render->hasNewLayout()) {
        /* do not call bridge->callLayout because render is not registered to page, so that
         page->GetRenderObject will not give the correct object. */
        RenderPageBase *page = RenderManager::GetInstance()->GetPage(pageId);
        if (page != nullptr) {
            WXComponent* component = (__bridge WXComponent *)(render->getContext());
            NSString* ns_instanceId = NSSTRING(pageId);
            
            float top = render->getLayoutPositionTop();
            float left = render->getLayoutPositionLeft();
            float height = render->getLayoutHeight();
            float width = render->getLayoutWidth();
            BOOL isRTL = render->getLayoutDirectionFromPathNode() == WeexCore::kDirectionRTL;
            WXComponentManager* manager = [WXSDKManager instanceForID:ns_instanceId].componentManager;
            CGRect frame = CGRectMake(isnan(WXCeilPixelValue(left))?0:WXCeilPixelValue(left),
                                      isnan(WXCeilPixelValue(top))?0:WXCeilPixelValue(top),
                                      isnan(WXCeilPixelValue(width))?0:WXCeilPixelValue(width),
                                      isnan(WXCeilPixelValue(height))?0:WXCeilPixelValue(height));
            [manager layoutComponent:component frame:frame isRTL:isRTL innerMainSize:render->getLargestMainSize()];
        }
        render->setHasNewLayout(false);
    }

    for (auto it = render->ChildListIterBegin(); it != render->ChildListIterEnd(); it ++) {
        WeexCore::RenderObject *child = static_cast<WeexCore::RenderObject *>(*it);
        if (child != nullptr) {
            [self _traverseTree:child index:(int)(it - render->ChildListIterBegin()) pageId:pageId];
        }
    }
}

+ (void)layoutRenderObject:(void*)object size:(CGSize)size page:(NSString*)pageId
{
    using namespace WeexCore;
    RenderObject* render = static_cast<RenderObject*>(object);
    std::pair<float, float> renderPageSize(size.width, size.height);
    
    render->calculateLayout(renderPageSize);
    [self _traverseTree:render index:0 pageId:[pageId UTF8String] ?: ""];
}

+ (void*)copyRenderObject:(void*)source replacedRef:(NSString*)ref
{
    using namespace WeexCore;
    RenderObject* sourceObject = static_cast<RenderObject*>(source);
    RenderObject* copyObject = static_cast<RenderObject*>(RenderCreator::GetInstance()->CreateRender(sourceObject->type(), sourceObject->ref()));
                                                          
    copyObject->CopyFrom(sourceObject);
    if (ref != nil) {
        copyObject->set_ref([ref UTF8String] ?: "");
    }

    if (sourceObject->type() == kRenderCellSlot || sourceObject->type() == kRenderCell) {
        RenderList* renderList = static_cast<RenderList*>(sourceObject->getParent());
        if (renderList != nullptr) {
            renderList->AddCellSlotCopyTrack(copyObject);
        }
    }
    return copyObject;
}

+ (void)addChildRenderObject:(void*)child toParent:(void*)parent
{
    (static_cast<WeexCore::RenderObject*>(parent))->AddRenderObject(-1, (static_cast<WeexCore::RenderObject*>(child)));
}

+ (void)removeRenderObjectFromMap:(NSString*)pageId object:(void*)object
{
    using namespace WeexCore;
    RenderPage* page = static_cast<RenderPage*>(RenderManager::GetInstance()->GetPage([pageId UTF8String] ?: ""));
    if (page != nullptr) {
        page->RemoveRenderFromRegisterMap(static_cast<RenderObject*>(object));
    }
}

+ (void)_parseStyleBeforehand:(NSDictionary *)styles key:(NSString *)key render:(WeexCore::RenderObject*)render reserveStyles:(bool)reserveStyles
{
    id data = styles[key];
    if (data) {
        ConvertToCString(data, ^(const char * value) {
            if (value != nullptr) {
                render->AddStyle([key UTF8String], value, reserveStyles);
            }
        });
    }
}

+ (WeexCore::RenderObject*)_parseRenderObject:(NSDictionary *)data parent:(WeexCore::RenderObject *)parent index:(int)index pageId:(const std::string&)pageId reserveStyles:(bool)reserveStyles
{
    using namespace WeexCore;
    
    const char* type = [data[@"type"] UTF8String];
    const char* ref = [data[@"ref"] UTF8String];
    if (type != nullptr && ref != nullptr) {
        RenderObject* render = (RenderObject *)RenderCreator::GetInstance()->CreateRender(type, ref);
        render->set_page_id(pageId);
        if (parent != nullptr){
            parent->AddRenderObject(index, render);
        }
        
        [data[@"attr"] enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            ConvertToCString(obj, ^(const char * value) {
                if (value != nullptr) {
                    render->AddAttr([key UTF8String], value);
                }
            });
        }];
        
        // margin/padding/borderWidth should be handled beforehand. Because maringLeft should override margin.
        NSDictionary* styles = data[@"style"];
        [self _parseStyleBeforehand:styles key:@"margin" render:render reserveStyles:reserveStyles];
        [self _parseStyleBeforehand:styles key:@"padding" render:render reserveStyles:reserveStyles];
        [self _parseStyleBeforehand:styles key:@"borderWidth" render:render reserveStyles:reserveStyles];
        [styles enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            if ([key isEqualToString:@"margin"] || [key isEqualToString:@"padding"] || [key isEqualToString:@"borderWidth"]) {
                return;
            }
            ConvertToCString(obj, ^(const char * value) {
                if (value != nullptr) {
                    render->AddStyle([key UTF8String], value, reserveStyles);
                }
            });
        }];
        
        for (id obj in data[@"event"]) {
            ConvertToCString(obj, ^(const char * value) {
                if (value != nullptr) {
                    render->AddEvent(value);
                }
            });
        }
        
        int childIndex = 0;
        for (NSDictionary* obj in data[@"children"]) {
            [self _parseRenderObject:obj parent:render index:childIndex ++ pageId:pageId reserveStyles:reserveStyles];
        }
        
        render->ApplyDefaultStyle(reserveStyles);
        render->ApplyDefaultAttr();
        
        return render;
    }
    return nullptr;
}

+ (std::vector<std::pair<std::string, std::string>>*)_parseMapValuePairs:(NSDictionary *)data
{
    std::vector<std::pair<std::string, std::string>>* result = new std::vector<std::pair<std::string, std::string>>();
    [data enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        ConvertToCString(obj, ^(const char * value) {
            if (value != nullptr) {
                result->emplace_back([key UTF8String], value);
            }
        });
    }];
    return result;
}

+ (void)callAddElement:(NSString*)pageId parentRef:(NSString*)parentRef data:(NSDictionary*)data index:(int)index
{
    using namespace WeexCore;
    
    const std::string page([pageId UTF8String] ?: "");
    RenderManager::GetInstance()->AddRenderObject(page, [parentRef UTF8String] ?: "", index, [&] (RenderPage* pageInstance) -> RenderObject* {
        return [self _parseRenderObject:data parent:nullptr index:0 pageId:page reserveStyles:pageInstance->reserve_css_styles()];
    });
}

+ (void)callCreateBody:(NSString*)pageId data:(NSDictionary*)data
{
    using namespace WeexCore;
    
    WXSDKInstance* sdkInstance = [WXSDKManager instanceForID:pageId];
    WXComponentManager* manager = sdkInstance.componentManager;
    if (!manager.isValid) {
        return;
    }
    
    SetConvertCurrentPage(pageId);
    const std::string page([pageId UTF8String] ?: "");
    RenderManager::GetInstance()->CreatePage(page, [&] (RenderPage* pageInstance) -> RenderObject* {
        pageInstance->set_before_layout_needed(false); // we do not need before and after layout
        pageInstance->set_after_layout_needed(false);
        pageInstance->set_platform_layout_needed(true);
        return [self _parseRenderObject:data parent:nullptr index:0 pageId:page reserveStyles:pageInstance->reserve_css_styles()];
    });
}

+ (void)callRemoveElement:(NSString*)pageId ref:(NSString*)ref
{
    WeexCore::WeexCoreManager::Instance()->script_bridge()->core_side()->RemoveElement([pageId UTF8String] ?: "", [ref UTF8String] ?: "");
}

+ (void)callMoveElement:(NSString*)pageId ref:(NSString*)ref parentRef:(NSString*)parentRef index:(int)index
{
    WeexCore::WeexCoreManager::Instance()->script_bridge()->core_side()->MoveElement([pageId UTF8String] ?: "", [ref UTF8String] ?: "", [parentRef UTF8String] ?: "", index);
}

+ (void)callUpdateAttrs:(NSString*)pageId ref:(NSString*)ref data:(NSDictionary*)data
{
    SetConvertCurrentPage(pageId);
    WeexCore::RenderManager::GetInstance()->UpdateAttr([pageId UTF8String] ?: "", [ref UTF8String] ?: "", [self _parseMapValuePairs:data]);
}

+ (void)callUpdateStyle:(NSString*)pageId ref:(NSString*)ref data:(NSDictionary*)data
{
    SetConvertCurrentPage(pageId);
    WeexCore::RenderManager::GetInstance()->UpdateStyle([pageId UTF8String] ?: "", [ref UTF8String] ?: "", [self _parseMapValuePairs:data]);
}

+ (void)callAddEvent:(NSString*)pageId ref:(NSString*)ref event:(NSString*)event
{
    WeexCore::WeexCoreManager::Instance()->script_bridge()->core_side()->AddEvent([pageId UTF8String] ?: "", [ref UTF8String] ?: "", [event UTF8String] ?: "");
}

+ (void)callRemoveEvent:(NSString*)pageId ref:(NSString*)ref event:(NSString*)event
{
    WeexCore::WeexCoreManager::Instance()->script_bridge()->core_side()->RemoveEvent([pageId UTF8String] ?: "", [ref UTF8String] ?: "", [event UTF8String] ?: "");
}

+ (void)callCreateFinish:(NSString*)pageId
{
    WeexCore::WeexCoreManager::Instance()->script_bridge()->core_side()->CreateFinish([pageId UTF8String] ?: "");
}

+ (void)callRefreshFinish:(NSString*)pageId
{
    WeexCore::WeexCoreManager::Instance()->script_bridge()->core_side()->RefreshFinish([pageId UTF8String] ?: "", nullptr, nullptr);
}

+ (void)callUpdateFinish:(NSString*)pageId
{
    WeexCore::WeexCoreManager::Instance()->script_bridge()->core_side()->UpdateFinish([pageId UTF8String] ?: "", nullptr, 0, nullptr, 0);
}

+ (void)registerCoreEnv:(NSString*)key withValue:(NSString*)value
{
    WeexCore::WeexCoreManager::Instance()->getPlatformBridge()->core_side()->RegisterCoreEnv([key UTF8String]?:"", [value UTF8String]?:"");
}

+ (void)setPageArgument:(NSString*)pageId key:(NSString*)key value:(NSString*)value
{
    WeexCore::RenderManager::GetInstance()->setPageArgument([pageId UTF8String]?:"", [key UTF8String]?:"", [value UTF8String]?:"");
}

+ (BOOL)isKeepingRawCssStyles:(NSString*)pageId
{
    RenderPageBase* page = RenderManager::GetInstance()->GetPage([pageId UTF8String] ?: "");
    if (page == nullptr) {
        return NO;
    }
    return static_cast<RenderPage*>(page)->reserve_css_styles();
}

@end
