/**
 * 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.
 */
package org.apache.weex.performance;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

import android.graphics.Rect;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import org.apache.weex.WXEnvironment;
import org.apache.weex.WXSDKInstance;
import org.apache.weex.WXSDKManager;
import org.apache.weex.bridge.WXBridgeManager;
import org.apache.weex.common.WXErrorCode;
import org.apache.weex.common.WXPerformance;
import org.apache.weex.common.WXRenderStrategy;
import org.apache.weex.ui.component.WXComponent;
import org.apache.weex.utils.WXExceptionUtils;
import org.apache.weex.utils.WXLogUtils;
import org.apache.weex.utils.WXUtils;

public class WXInstanceApm {

    public static final String WEEX_PAGE_TOPIC = "weex_page";

    /************** properties *****************/
    public static final String KEY_PROPERTIES_ERROR_CODE = "wxErrorCode";
    //public static final String KEY_PAGE_PROPERTIES_LAUNCH_ID = "wxLaunchId";
    public static final String KEY_PAGE_PROPERTIES_BIZ_ID = "wxBizID";
    public static final String KEY_PAGE_PROPERTIES_BUBDLE_URL = "wxBundleUrl";
    public static final String KEY_PAGE_PROPERTIES_JSLIB_VERSION = "wxJSLibVersion";
    public static final String KEY_PAGE_PROPERTIES_WEEX_VERSION = "wxSDKVersion";
    public static final String KEY_PAGE_PROPERTIES_REQUEST_TYPE = "wxRequestType";
    public static final String KEY_PAGE_PROPERTIES_CACHE_TYPE = "wxCacheType";
    public static final String KEY_PAGE_PROPERTIES_CACHE_INFO = "wxZCacheInfo";
    public static final String KEY_PAGE_PROPERTIES_JS_FM_INI = "wxJsFrameworkInit";
    public static final String KEY_PAGE_PROPERTIES_CONTAINER_NAME = "wxContainerName";
    public static final String KEY_PAGE_PROPERTIES_INSTANCE_TYPE = "wxInstanceType";
    public static final String KEY_PAGE_PROPERTIES_PARENT_PAGE = "wxParentPage";
    public static final String KEY_PAGE_PROPERTIES_BUNDLE_TYPE = "wxBundleType";
    public static final String KEY_PAGE_PROPERTIES_RENDER_TYPE = "wxRenderType";
    public static final String KEY_PAGE_PROPERTIES_UIKIT_TYPE = "wxUIKitType";

    /************** stages *****************/
    public static final String KEY_PAGE_STAGES_CONTAINER_READY = "wxContainerReady";
    public static final String KEY_PAGE_STAGES_DOWN_BUNDLE_START = "wxStartDownLoadBundle";
    public static final String KEY_PAGE_STAGES_DOWN_BUNDLE_END = "wxEndDownLoadBundle";
    public static final String KEY_PAGE_STAGES_RENDER_ORGIGIN = "wxRenderTimeOrigin";
    public static final String KEY_PAGE_STAGES_LOAD_BUNDLE_START = "wxStartLoadBundle";
    public static final String KEY_PAGE_STAGES_LOAD_BUNDLE_END = "wxEndLoadBundle";
    public static final String KEY_PAGE_STAGES_FIRST_INTERACTION_VIEW = "wxFirstInteractionView";
    public static final String KEY_PAGE_STAGES_CREATE_FINISH= "wxJSBundleCreateFinish";
    public static final String KEY_PAGE_STAGES_FSRENDER = "wxFsRender";
    public static final String KEY_PAGE_STAGES_NEW_FSRENDER = "wxNewFsRender";
    public static final String KEY_PAGE_STAGES_END_EXCUTE_BUNDLE = "wxEndExecuteBundle";
    public static final String KEY_PAGE_STAGES_INTERACTION = "wxInteraction";
    public static final String KEY_PAGE_STAGES_DESTROY = "wxDestroy";

    //Custom preprocessing start, called when activity created or other time. Called by other activity
    public static final String KEY_PAGE_STAGES_CUSTOM_PREPROCESS_START = "wxCustomPreprocessStart";
    //Custom preprocessing end, called when you'are able to start weex render. Called by other activity
    public static final String KEY_PAGE_STAGES_CUSTOM_PREPROCESS_END = "wxCustomPreprocessEnd";

    /************** stats *****************/
    public static final String KEY_PAGE_STATS_BUNDLE_SIZE = "wxBundleSize";
    public static final String KEY_PAGE_STATS_FS_CALL_JS_TIME = "wxFSCallJsTotalTime";
    public static final String KEY_PAGE_STATS_FS_CALL_JS_NUM = "wxFSCallJsTotalNum";
    public static final String KEY_PAGE_STATS_FS_TIMER_NUM = "wxFSTimerCount";
    public static final String KEY_PAGE_STATS_FS_CALL_NATIVE_TIME = "wxFSCallNativeTotalTime";
    public static final String KEY_PAGE_STATS_FS_CALL_NATIVE_NUM = "wxFSCallNativeTotalNum";
    public static final String KEY_PAGE_STATS_FS_CALL_EVENT_NUM = "wxFSCallEventTotalNum";
    public static final String KEY_PAGE_STATS_FS_REQUEST_NUM = "wxFSRequestNum";
    public static final String KEY_PAGE_STATS_CELL_EXCEED_NUM = "wxCellExceedNum";
    public static final String KEY_PAGE_STATS_MAX_DEEP_VIEW = "wxMaxDeepViewLayer";
    public static final String KEY_PAGE_STATS_MAX_DEEP_DOM = "wxMaxDeepVDomLayer";
    public static final String KEY_PAGE_STATS_MAX_COMPONENT_NUM = "wxMaxComponentCount";
    public static final String KEY_PAGE_STATS_WRONG_IMG_SIZE_COUNT = "wxWrongImgSizeCount";
    public static final String KEY_PAGE_STATS_EMBED_COUNT = "wxEmbedCount";
    public static final String KEY_PAGE_STATS_LARGE_IMG_COUNT = "wxLargeImgMaxCount";
    public static final String KEY_PAGE_STATS_BODY_RATIO = "wxBodyRatio";
    public static final String KEY_PAGE_STATS_SCROLLER_NUM = "wxScrollerCount";
    public static final String KEY_PAGE_STATS_CELL_DATA_UN_RECYCLE_NUM = "wxCellDataUnRecycleCount";
    public static final String KEY_PAGE_STATS_CELL_UN_RE_USE_NUM = "wxCellUnReUseCount";
    public static final String KEY_PAGE_STATS_IMG_UN_RECYCLE_NUM = "wxImgUnRecycleCount";

    public static final String KEY_PAGE_STATS_I_SCREEN_VIEW_COUNT = "wxInteractionScreenViewCount";
    public static final String KEY_PAGE_STATS_I_ALL_VIEW_COUNT = "wxInteractionAllViewCount";
    public static final String KEY_PAGE_STATS_I_COMPONENT_CREATE_COUNT = "wxInteractionComponentCreateCount";
    public static final String KEY_PAGE_ANIM_BACK_NUM = "wxAnimationInBackCount";
    public static final String KEY_PAGE_TIMER_BACK_NUM = "wxTimerInBackCount";
    public static final String KEY_PAGE_STATS_ACTUAL_DOWNLOAD_TIME = "wxActualNetworkTime";

    public static final String KEY_PAGE_STATS_IMG_LOAD_NUM = "wxImgLoadCount";
    public static final String KEY_PAGE_STATS_IMG_LOAD_SUCCESS_NUM = "wxImgLoadSuccessCount";
    public static final String KEY_PAGE_STATS_IMG_LOAD_FAIL_NUM = "wxImgLoadFailCount";
    public static final String KEY_PAGE_STATS_NET_NUM = "wxNetworkRequestCount";
    public static final String KEY_PAGE_STATS_NET_SUCCESS_NUM = "wxNetworkRequestSuccessCount";
    public static final String KEY_PAGE_STATS_NET_FAIL_NUM = "wxNetworkRequestFailCount";
    public static final String KEY_PAGE_STATS_JSLIB_INIT_TIME = "wxJSLibInitTime";
    public static final String KEY_PAGE_STATS_VIEW_CREATE_COST = "wxViewCost";
    public static final String KEY_PAGE_STATS_COMPONENT_CREATE_COST = "wxComponentCost";
    public static final String KEY_PAGE_STATS_EXECUTE_JS_CALLBACK_COST = "wxExecJsCallBack";
    public static final String KEY_PAGE_STATS_LAYOUT_TIME = "wxLayoutTime";


    /************** value *****************/
    public static final String VALUE_ERROR_CODE_DEFAULT = "0";
    public static final String VALUE_BUNDLE_LOAD_LENGTH = "wxLoadedLength";

    private String mInstanceId;
    private IWXApmMonitorAdapter apmInstance;
    private Map<String, Double> recordStatsMap;
    public final Map<String, Long> stageMap;
    private Map<String,Object> mPropertiesMap;
    private boolean isFSEnd;
    private boolean mHasInit = false;
    private boolean mEnd = false;
    private boolean hasRecordFistInteractionView =false;
    public final Map<String,Object> extInfo;
    public boolean forceStopRecordInteraction = false;
    public Rect instanceRect;
    public String reportPageName;
    public boolean hasReportLayerOverDraw = false;
    public boolean hasAddView;
    private Handler mUIHandler;

    public Set<String> exceptionRecord = new CopyOnWriteArraySet<String>();

    private double interactionLayoutTime;
    public long componentCreateTime;
    private long interactionComponentCreateTime;
    public long viewCreateTime;
    private long interactionViewCreateTime;
    //next version
    private long wxExecJsCallBackTime;
    private long interactionJsCallBackTime;


    private boolean mHasRecordDetailData = false;

    /**
     * send performance value to js
     **/
    private boolean hasSendInteractionToJS = false;
    public volatile boolean isReady = true;

    public WXInstanceApm(String instanceId) {
        mInstanceId = instanceId;
        extInfo = new ConcurrentHashMap<>();
        stageMap = new ConcurrentHashMap<>();
        mUIHandler = new Handler(Looper.getMainLooper());
        recordStatsMap = new ConcurrentHashMap<>();
        mPropertiesMap = new ConcurrentHashMap<>();
        IApmGenerator generator = WXSDKManager.getInstance().getApmGenerater();
        if (null != generator) {
            apmInstance = generator.generateApmInstance(WEEX_PAGE_TOPIC);
        }
    }

    public void onInstanceReady(boolean isPreDownLoad){
        this.isReady = true;
        if (isPreDownLoad){
            onStage(KEY_PAGE_STAGES_DOWN_BUNDLE_START);
        }
        doInit();
        for (Map.Entry<String,Long> stage:stageMap.entrySet()){
            sendStageInfo(stage.getKey(),stage.getValue());
        }
        for (Map.Entry<String,Double> stats:recordStatsMap.entrySet()){
           sendStats(stats.getKey(),stats.getValue());
        }
        for (Map.Entry<String,Object> p:mPropertiesMap.entrySet()){
           sendProperty(p.getKey(),p.getValue());
        }
    }

    /**
     * record event
     */
    public void onEvent(String name, Object value) {
        if (null == apmInstance) {
            return;
        }
        apmInstance.onEvent(name, value);
    }

    /**
     * record stage
     */
    public void onStage(String name) {
        long time =  WXUtils.getFixUnixTime();
        onStageWithTime(name,time);
    }

    /**
     *
     * @param name stage
     * @param time unixTime ,plz use WXUtils.getFixUnixTime
     */
    public void onStageWithTime(String name,long time){
        if (mEnd){
            return;
        }
        if (null == name){
            return;
        }
        stageMap.put(name,time);
        if (isReady){
            sendStageInfo(name,time);
        }
    }

    private void sendStageInfo(String name,long time){
        if(WXAnalyzerDataTransfer.isOpenPerformance){
            WXAnalyzerDataTransfer.transferPerformance(mInstanceId,"stage",name,time);
        }

        if (KEY_PAGE_STAGES_RENDER_ORGIGIN.equalsIgnoreCase(name)){
            mUIHandler.postDelayed(jsPerformanceCallBack,8000);
        }

        if (null == apmInstance) {
            return;
        }

        apmInstance.onStage(name, time);
    }

    private Runnable jsPerformanceCallBack = new Runnable() {
        @Override
        public void run() {
            sendPerformanceToJS();
        }
    };

    /**
     * record property
     */
    public void addProperty(String key, Object value) {
        if (mEnd){
            return;
        }
        if (null == key || null == value){
            return;
        }
        mPropertiesMap.put(key,value);
        if (isReady){
            sendProperty(key,value);
        }
    }

    private void sendProperty(String key,Object value){
        if(WXAnalyzerDataTransfer.isOpenPerformance){
            WXAnalyzerDataTransfer.transferPerformance(mInstanceId,"properties",key,value);
        }

        if (null == apmInstance) {
            return;
        }
        apmInstance.addProperty(key, value);
    }

    /**
     * record statistic
     */
    public void addStats(String key, double value) {
        if (mEnd){
            return;
        }
        if (null == key){
            return;
        }
        recordStatsMap.put(key,value);
        if (isReady){
            sendStats(key,value);
        }
    }

    private void sendStats(String key,double value){
        if(WXAnalyzerDataTransfer.isOpenPerformance){
            WXAnalyzerDataTransfer.transferPerformance(mInstanceId,"stats",key,value);
        }

        if (null == apmInstance) {
            return;
        }
        apmInstance.addStats(key, value);
    }


    public boolean hasInit(){
        return mHasInit;
    }

    /**
     * start record
     */
    public void doInit() {
        if (!isReady){
            return;
        }
        if (mHasInit){
            return;
        }
        mHasInit = true;
        if (null == apmInstance) {
            return;
        }
        apmInstance.onStart(mInstanceId);
        WXSDKInstance instance = WXSDKManager.getInstance().getAllInstanceMap().get(mInstanceId);
        String url = null == instance ? "unKnowUrl" : instance.getBundleUrl();
        addProperty(KEY_PAGE_PROPERTIES_BUBDLE_URL, url);
        addProperty(KEY_PROPERTIES_ERROR_CODE, VALUE_ERROR_CODE_DEFAULT);
        addProperty(KEY_PAGE_PROPERTIES_JSLIB_VERSION, WXEnvironment.JS_LIB_SDK_VERSION);
        addProperty(KEY_PAGE_PROPERTIES_WEEX_VERSION, WXEnvironment.WXSDK_VERSION);
        addStats("wxReInitCount", WXBridgeManager.reInitCount);
        if (null != instance){
            addProperty(KEY_PAGE_PROPERTIES_UIKIT_TYPE, instance.getRenderType());
        }

        addProperty("wxUseRuntimeApi",WXEnvironment.sUseRunTimeApi);
        if (instance != null && (instance.getRenderStrategy() == WXRenderStrategy.DATA_RENDER
                || instance.getRenderStrategy() == WXRenderStrategy.DATA_RENDER_BINARY)) {
            addProperty(KEY_PAGE_PROPERTIES_RENDER_TYPE, WXEnvironment.EAGLE);
        }
        if (null != instance) {
            for (Map.Entry<String, String> entry : instance.getContainerInfo().entrySet()) {
                addProperty(entry.getKey(), entry.getValue());
            }
        }
    }

    public void setPageName(String pageName) {
        if (TextUtils.isEmpty(pageName)) {
            WXSDKInstance instance = WXSDKManager.getInstance().getAllInstanceMap().get(mInstanceId);
            if (null != instance) {
                pageName = instance.getContainerInfo().get(KEY_PAGE_PROPERTIES_CONTAINER_NAME);
            }
        }
        reportPageName = null == apmInstance?pageName:apmInstance.parseReportUrl(pageName);
        reportPageName = TextUtils.isEmpty(reportPageName) ? "emptyPageName" : reportPageName;
        addProperty(KEY_PAGE_PROPERTIES_BIZ_ID, reportPageName);
    }

    public void onAppear(){
        if (null == apmInstance) {
            return;
        }
        apmInstance.onAppear();
    }

    public void onDisAppear(){
        if (null == apmInstance) {
            return;
        }
        apmInstance.onDisappear();
    }

    /**
     * end record
     */
    public void onEnd() {
        if (null == apmInstance || mEnd) {
            return;
        }
        new Handler(Looper.getMainLooper()).removeCallbacks(delayCollectDataTask);
        recordPerformanceDetailData();
        exceptionRecord.clear();
        mUIHandler.removeCallbacks(jsPerformanceCallBack);
        onStage(KEY_PAGE_STAGES_DESTROY);
        if (mHasInit && null != apmInstance){
            apmInstance.onEnd();
        }
        mEnd = true;
        if (WXEnvironment.isApkDebugable()){
            printLog();
        }
    }

    public void doDelayCollectData(){
        new Handler(Looper.getMainLooper()).postDelayed(delayCollectDataTask,8000);
    }

    private Runnable delayCollectDataTask = new Runnable() {
        @Override
        public void run() {
            recordPerformanceDetailData();
        }
    };


    private void printLog(){
        Long startDownLoad = stageMap.get(KEY_PAGE_STAGES_DOWN_BUNDLE_START);
        Long endDownLoad = stageMap.get(KEY_PAGE_STAGES_DOWN_BUNDLE_END);
        Long interaction = stageMap.get(KEY_PAGE_STAGES_INTERACTION);
        Long containerReady = stageMap.get(KEY_PAGE_STAGES_CONTAINER_READY);
        if (null != endDownLoad && null != startDownLoad){
            WXLogUtils.d("test->", "downLoadTime: "+ (endDownLoad - startDownLoad));
        }
        if (null != endDownLoad && null != interaction){
            WXLogUtils.d("test->", "renderTime: "+ (interaction - endDownLoad));
        }
        if (null != containerReady && null !=interaction){
            WXLogUtils.d("test->", "showTime: "+ (interaction - containerReady));
        }

    }

    public void arriveNewFsRenderTime(){
        if (null == apmInstance){
            return;
        }
        onStage(WXInstanceApm.KEY_PAGE_STAGES_NEW_FSRENDER);
    }

    public void arriveFSRenderTime() {
        if (null == apmInstance){
            return;
        }
        isFSEnd = true;
        onStage(WXInstanceApm.KEY_PAGE_STAGES_FSRENDER);
    }

    public void arriveInteraction(WXComponent targetComponent) {
        if (null == apmInstance || null == targetComponent || targetComponent.getInstance() == null) {
            return;
        }

        if (WXAnalyzerDataTransfer.isOpenPerformance){
            WXAnalyzerDataTransfer.transferInteractionInfo(targetComponent);
        }


        if (null == apmInstance){
            return;
        }

        WXPerformance performanceRecord = targetComponent.getInstance().getWXPerformance();
        if (null == performanceRecord){
            return;
        }

        long curTime = WXUtils.getFixUnixTime();

        if (WXAnalyzerDataTransfer.isInteractionLogOpen()){
            Log.d(WXAnalyzerDataTransfer.INTERACTION_TAG, "[client][wxinteraction]"
                + targetComponent.getInstance().getInstanceId()
                +","+targetComponent.getComponentType()
                +","+targetComponent.getRef()
                +","+targetComponent.getStyles()
                +","+targetComponent.getAttrs()
            );
        }

        if (!hasRecordFistInteractionView){
            onStage(KEY_PAGE_STAGES_FIRST_INTERACTION_VIEW);
            hasRecordFistInteractionView = true;
        }
        if (forceStopRecordInteraction){
            return;
        }
        long now = WXUtils.getFixUnixTime();
        if (now - preUpdateTime > 50){
            //for performance, reduce jni calls
            WXBridgeManager.getInstance().onInteractionTimeUpdate(mInstanceId);
            preUpdateTime = now;
        }

        interactionComponentCreateTime = componentCreateTime;
        interactionViewCreateTime = viewCreateTime;
        Double layoutTime = recordStatsMap.get("wxLayoutTime");
        interactionLayoutTime = layoutTime ==null? 0:layoutTime;

        performanceRecord.interactionTime = curTime - performanceRecord.renderUnixTimeOrigin;
        performanceRecord.interactionRealUnixTime = System.currentTimeMillis();
        onStageWithTime(KEY_PAGE_STAGES_INTERACTION,curTime);

        updateDiffStats(KEY_PAGE_STATS_I_SCREEN_VIEW_COUNT, 1);
        updateMaxStats(KEY_PAGE_STATS_I_ALL_VIEW_COUNT, performanceRecord.localInteractionViewAddCount);
        WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(mInstanceId);
        if (null != instance) {
            updateMaxStats(KEY_PAGE_STATS_I_COMPONENT_CREATE_COUNT, instance.getWXPerformance().componentCount);
        }
    }

    private long preUpdateTime = 0;

    public void updateFSDiffStats(String name, double diffValue) {
        if (null == apmInstance || isFSEnd) {
            return;
        }
        updateDiffStats(name, diffValue);
    }

    public void recordPerformanceDetailData(){
        if (mHasRecordDetailData){
            return;
        }
        mHasRecordDetailData = true;
        addStats(KEY_PAGE_STATS_VIEW_CREATE_COST,interactionViewCreateTime);
        addStats(KEY_PAGE_STATS_COMPONENT_CREATE_COST,interactionComponentCreateTime);
        addStats(KEY_PAGE_STATS_EXECUTE_JS_CALLBACK_COST,interactionJsCallBackTime);
        addStats(KEY_PAGE_STATS_LAYOUT_TIME,interactionLayoutTime);
    }

    public void updateDiffStats(String name, double diffValue) {
        if (null == apmInstance) {
            return;
        }
        Double preVal = recordStatsMap.containsKey(name) ? recordStatsMap.get(name) : 0;
        //fix by use ConcurrentHashMap,but not sure,so report if error still happen
        if (null == preVal){
            WXExceptionUtils.commitCriticalExceptionRT(
                "",
                WXErrorCode.WX_ERR_HASH_MAP_TMP,
                "updateDiffStats",
                "key : "+name,
                null
            );
            return;
        }

        double currentValue = preVal + diffValue;
        addStats(name, currentValue);
    }

    public void updateMaxStats(String name, double currentVal) {
        if (null == apmInstance) {
            return;
        }
        Double maxValue = recordStatsMap.containsKey(name) ? recordStatsMap.get(name) : 0;
        //fix by use ConcurrentHashMap,but not sure,so report if error still happen
        if (null == maxValue){
            WXExceptionUtils.commitCriticalExceptionRT(
                "",
                WXErrorCode.WX_ERR_HASH_MAP_TMP,
                "updateMaxStats",
                "key : "+name,
                null
            );
            return;
        }
        if (maxValue < currentVal) {
            maxValue = currentVal;
            addStats(name, maxValue);
        }
    }

    public void updateRecordInfo(Map<String, Object> extParams) {
        if (null == apmInstance || null == extParams) {
            return;
        }

        addPropeyFromExtParms(KEY_PAGE_PROPERTIES_REQUEST_TYPE, KEY_PAGE_PROPERTIES_REQUEST_TYPE, extParams);
        addPropeyFromExtParms("cacheType", KEY_PAGE_PROPERTIES_CACHE_TYPE, extParams);
        addPropeyFromExtParms("zCacheInfo", KEY_PAGE_PROPERTIES_CACHE_INFO, extParams);

        addStats(KEY_PAGE_STATS_JSLIB_INIT_TIME, WXEnvironment.sJSLibInitTime);
        addProperty(KEY_PAGE_PROPERTIES_JS_FM_INI, WXEnvironment.JsFrameworkInit);

        Object wxNetLibDownBundleTime = extParams.get("actualNetworkTime");
        if (wxNetLibDownBundleTime instanceof Long) {
            updateDiffStats(KEY_PAGE_STATS_ACTUAL_DOWNLOAD_TIME, ((Long)wxNetLibDownBundleTime).doubleValue());
        }
    }

    private void addPropeyFromExtParms(String fromKey, String toKey, Map<String, Object> extParams) {
        Object value = extParams.get(fromKey);
        if (value instanceof String) {
            addProperty(toKey, value);
        }
    }

    /************** called by IWXHttpAdapter implementer *****************/

    public void actionNetRequest() {
        if (!isFSEnd) {
            updateFSDiffStats(WXInstanceApm.KEY_PAGE_STATS_FS_REQUEST_NUM, 1);
        }
        updateDiffStats(WXInstanceApm.KEY_PAGE_STATS_NET_NUM, 1);
    }

    public void actionNetResult(boolean succeed, String errorCode) {
        if (succeed) {
            updateDiffStats(WXInstanceApm.KEY_PAGE_STATS_NET_SUCCESS_NUM, 1);
        } else {
            updateDiffStats(WXInstanceApm.KEY_PAGE_STATS_NET_FAIL_NUM, 1);
        }
    }

    /************** called by IWXImgLoaderAdapter implementer *****************/

    public void actionLoadImg() {
        updateDiffStats(WXInstanceApm.KEY_PAGE_STATS_IMG_LOAD_NUM, 1);
    }

    public void actionLoadImgResult(boolean succeed, String errorCode) {
        if (succeed) {
            updateDiffStats(WXInstanceApm.KEY_PAGE_STATS_IMG_LOAD_SUCCESS_NUM, 1);
        } else {
            updateDiffStats(WXInstanceApm.KEY_PAGE_STATS_IMG_LOAD_FAIL_NUM, 1);
        }
    }

    public void sendPerformanceToJS() {
        if (hasSendInteractionToJS) {
            return;
        }
        hasSendInteractionToJS = true;
        WXSDKInstance instance = WXSDKManager.getInstance().getAllInstanceMap().get(mInstanceId);
        if (null == instance) {
            return;
        }

        Map<String,String> sendProperties = new HashMap<>(2);
        sendProperties.put(KEY_PAGE_PROPERTIES_BIZ_ID,reportPageName);
        sendProperties.put(KEY_PAGE_PROPERTIES_BUBDLE_URL,instance.getBundleUrl());

        Map<String,Long> sendStage = new HashMap<>(1);
        sendStage.put(KEY_PAGE_STAGES_INTERACTION,instance.getWXPerformance().interactionRealUnixTime);

        Map<String, Object> data = new HashMap<>(2);
        data.put("stage",sendStage);
        data.put("properties",sendProperties);

        instance.fireGlobalEventCallback("wx_apm", data);
    }


    public String toPerfString() {
        Long start = stageMap.get(KEY_PAGE_STAGES_RENDER_ORGIGIN);
        Long end = stageMap.get(KEY_PAGE_STAGES_INTERACTION);
        Long wxNewFsRender = stageMap.get(KEY_PAGE_STAGES_NEW_FSRENDER);
        StringBuilder builder = new StringBuilder();
        if(start != null && end != null){
            builder.append("interactiveTime " + (end - start) + "ms");
        }
        if(wxNewFsRender != null){
            builder.append(" wxNewFsRender " + (wxNewFsRender) + "ms");
        }
        return builder.toString();
   }

   public void updateNativePerformanceData(Map<String,String> nativePerformanceData){
        if (null == nativePerformanceData){
            return;
        }
        for (Map.Entry<String,String> entry : nativePerformanceData.entrySet()){
            double value = -1;
            try {
                value = Double.valueOf(entry.getValue());
            }catch (Exception e){
                e.printStackTrace();
            }
            if (value != -1){
                recordStatsMap.put(entry.getKey(),value);
            }
        }
   }
 }
