text: import utils from './utils';
  import parsePage from './parsePage';
  import * as eventDefine from './constants';
  import * as reportRealtimeAction from './logReport';
  
  
  
  var getRouteToPage;
  var getWebviewIdToPage;
  var setWxRouteBegin;
  var setWxRoute;
  var setWxConfig;
  var reset;
  var pageHolder;
  var getCurrentPages;
  var getCurrentPage;
  
  
  var pageStack = [];
  var tabBars = [];//tab栏url列表
  var currentPage;
  __wxConfig__.tabBar &&
  __wxConfig__.tabBar.list &&
  "object" === typeof(__wxConfig__.tabBar.list) &&
  "function" == typeof __wxConfig__.tabBar.list.forEach &&
  __wxConfig__.tabBar.list.forEach(function(item) {
      tabBars.push(item.pagePath);
  });
  
  var app = {
      appRouteTime: 0,
      newPageTime: 0,
      pageReadyTime: 0
  };
  
  var speedReport = function(key, startTime, endTime) {
      Reporter.speedReport({
          key: key,
          timeMark: {
              startTime: startTime,
              endTime: endTime
          }
      });
  };
  
  var pageStackObjs = {};
  var pageRegObjs = {};//key:pathname
  var pageIndex = 0;
  
  getCurrentPage = function() {
      return currentPage
  };
  getCurrentPages = function() {
      var pageArr = [];
      pageStack.forEach(function(pageObj) {
          pageArr.push(pageObj.page);
      });
      return pageArr;
  };
  pageHolder = function(pageObj) {//Page 接口
      if (!__wxRouteBegin) {
          throw utils.error("Page 注册错误", "Please do not register multiple Pages in " + __wxRoute + ".js");
          new utils.AppServiceEngineKnownError("Please do not register multiple Pages in " + __wxRoute + ".js");
      }
  
      __wxRouteBegin = !1;
      var pages = __wxConfig__.pages,
          pagePath = pages[pageIndex];
      pageIndex++;
      if ("Object" !== utils.getDataType(pageObj)) {
          throw utils.error("Page 注册错误", "Options is not object: " + JSON.stringify(pageObj) + " in " + __wxRoute + ".js")
          new utils.AppServiceEngineKnownError("Options is not object: " + JSON.stringify(pageObj) + " in " + __wxRoute + ".js");
      }
      utils.info("Register Page: " + pagePath);
      pageRegObjs[pagePath] = pageObj;
  };
  var pageInitData = utils.surroundByTryCatch(
      function(pageObj, webviewId) {
          utils.info("Update view with init data");
          var ext = {};
          ext.webviewId = webviewId,
          ext.enablePullUpRefresh = pageObj.hasOwnProperty("onReachBottom");
          var params = {
              data: {
                  data: pageObj.data,
                  ext: ext,
                  options: {
                      firstRender: !0
                  }
              }
          };
          utils.publish("appDataChange", params, [webviewId]);
      }
  );
  var pageParse = function(routePath, webviewId, params) {//解析page e:pagepath t:webviewId params:
      var curPageObj = undefined;
      routePath = routePath.replace(/\.htm[^\.]*$/,'');
      if (pageRegObjs.hasOwnProperty(routePath)) {
          curPageObj = pageRegObjs[routePath];
      } else {
          utils.warn("Page route 错误", "Page[" + routePath + "] not found. May be caused by: 1. Forgot to add page route in app.json. 2. Invoking Page() in async task.");
          curPageObj = {};
      }
      app.newPageTime = Date.now()
      var page = new parsePage(curPageObj, webviewId, routePath)
      pageInitData(page, webviewId)
      if(utils.isDevTools()){
          __wxAppData[routePath] = page.data
          __wxAppData[routePath].__webviewId__ = webviewId
          utils.publish(eventDefine.UPDATE_APP_DATA)
      }
      currentPage = {
          page: page,
          webviewId: webviewId,
          route: routePath
      };
      pageStack.push(currentPage);
      page.onLoad(params);
      page.onShow();
      pageStackObjs[webviewId] = {
          page: page,
          route: routePath
      };
      reportRealtimeAction.triggerAnalytics("enterPage", page);
      speedReport("appRoute2newPage", app.appRouteTime, app.newPageTime);
  };
  
  var pageHide = function(pageItem) {//执行page hide event
      pageItem.page.onHide();
      reportRealtimeAction.triggerAnalytics("leavePage", pageItem.page);
  };
  
  var pageUnload = function(pageItem) {//do page unload
      pageItem.page.onUnload();
      utils.isDevTools() && (delete __wxAppData[pageItem.route], utils.publish(eventDefine.UPDATE_APP_DATA));
      delete pageStackObjs[pageItem.webviewId];
      pageStack = pageStack.slice(0, pageStack.length - 1);
      reportRealtimeAction.triggerAnalytics("leavePage", pageItem.page);
  };
  
  var isTabBarsPage = function(pageItem) {//
      return tabBars.indexOf(pageItem.route) !== -1 || tabBars.indexOf(pageItem.route + ".html") !== -1;
  };
  
  var skipPage = function(routePath, pWebViewId, pageParams, pApiKey) {//打开、跳转页面
      utils.info("On app route: " + routePath)
      app.appRouteTime = Date.now()
      if ("navigateTo" === pApiKey) {
          currentPage && pageHide(currentPage);
          pageStackObjs.hasOwnProperty(pWebViewId) ?
              utils.error("Page route 错误(system error)", "navigateTo with an already exist webviewId " + pWebViewId) :
              pageParse(routePath, pWebViewId, pageParams);
      } else if ("redirectTo" === pApiKey) {
          currentPage && pageUnload(currentPage);
          pageStackObjs.hasOwnProperty(pWebViewId) ?
              utils.error("Page route 错误(system error)", "redirectTo with an already exist webviewId " + pWebViewId) :
              pageParse(routePath, pWebViewId, pageParams);
      }else if ("navigateBack" === pApiKey) {
          for (var isExist = !1,i = pageStack.length - 1; i >= 0; i--) {
              var pageItem = pageStack[i];
              if (pageItem.webviewId === pWebViewId) {
                  isExist = !0;
                  currentPage = pageItem;
                  pageItem.page.onShow();
                  reportRealtimeAction.triggerAnalytics("enterPage", pageItem);
                  break;
              }
              pageUnload(pageItem);
          }
          isExist || utils.error("Page route 错误(system error)", "navigateBack with an unexist webviewId " + pWebViewId);
      }else if ("reLaunch" === pApiKey) {
          currentPage && pageUnload(currentPage);
          pageStackObjs.hasOwnProperty(pWebViewId) ?
            utils.error("Page route 错误(system error)", "redirectTo with an already exist webviewId " + pWebViewId) :
           pageParse(routePath, pWebViewId, pageParams);
      } else if ("switchTab" === pApiKey) {
          for (var onlyOnePage = !0; pageStack.length > 1;) {
              pageUnload(pageStack[pageStack.length - 1]);
              onlyOnePage = !1;
          }
          if (pageStack[0].webviewId === pWebViewId ) {
              currentPage = pageStack[0];
              onlyOnePage || currentPage.page.onShow();
          } else if (isTabBarsPage(pageStack[0]) ? onlyOnePage && pageHide(pageStack[0]) : pageUnload(pageStack[0]), pageStackObjs.hasOwnProperty(pWebViewId)) {
              var pageObj = pageStackObjs[pWebViewId].page;
              currentPage = {
                  webviewId: pWebViewId,
                  route: routePath,
                  page: pageObj
              }
              pageStack = [currentPage];
              pageObj.onShow();
              reportRealtimeAction.triggerAnalytics("enterPage", pageObj);
          } else {
              pageStack = [];
              pageParse(routePath, pWebViewId, pageParams);
          }
      } else {
          "appLaunch" === pApiKey ?
              pageStackObjs.hasOwnProperty(pWebViewId) ?
                  utils.error("Page route 错误(system error)", "appLaunch with an already exist webviewId " + pWebViewId) :
                  pageParse(routePath, pWebViewId, pageParams)
              : utils.error("Page route 错误(system error)", "Illegal open type: " + pApiKey);
      }
  };
  
  var doWebviewEvent = function(pWebviewId, pEvent, params) {//do dom ready
      if (!pageStackObjs.hasOwnProperty(pWebviewId)) {
          return utils.warn("事件警告", "OnWebviewEvent: " + pEvent + ", WebviewId: " + pWebviewId + " not found");
      }
      var pageItem = pageStackObjs[pWebviewId],
          pageObj = pageItem.page;
      return pEvent === eventDefine.DOM_READY_EVENT ?
          (
              app.pageReadyTime = Date.now(),
              utils.info("Invoke event onReady in page: " + pageItem.route),
              pageObj.onReady(),reportRealtimeAction.triggerAnalytics("pageReady", pageObj),
              void speedReport("newPage2pageReady", app.newPageTime, app.pageReadyTime)
          ) :
          (
              utils.info("Invoke event " + pEvent + " in page: " + pageItem.route),
              pageObj.hasOwnProperty(pEvent) ?
                  utils.safeInvoke.call(pageObj, pEvent, params) :
                  utils.warn("事件警告", "Do not have " + pEvent + " handler in current page: " + pageItem.route + ". Please make sure that " + pEvent + " handler has been defined in " + pageItem.route + ", or " + pageItem.route + " has been added into app.json")
          );
  };
  
  var pullDownRefresh = function(pWebviewId) {//do pulldownrefresh
      pageStackObjs.hasOwnProperty(pWebviewId) ||
      utils.warn("事件警告", "onPullDownRefresh WebviewId: " + pWebviewId + " not found");
      var pageItem = pageStackObjs[pWebviewId],
          pageObj = pageItem.page;
      if(pageObj.hasOwnProperty("onPullDownRefresh")){
          utils.info("Invoke event onPullDownRefresh in page: " + pageItem.route)
          utils.safeInvoke.call(pageObj, "onPullDownRefresh")
          reportRealtimeAction.triggerAnalytics("pullDownRefresh", pageObj)
      }
  }
  
  var invokeShareAppMessage = function(params, pWebviewId) {//invoke event onShareAppMessage
      var shareParams = params,
          pageItem = pageStackObjs[pWebviewId],
          pageObj = pageItem.page,
          eventName = "onShareAppMessage";
      if (pageObj.hasOwnProperty(eventName)) {
          utils.info("Invoke event onShareAppMessage in page: " + pageItem.route);
          var shareObj = utils.safeInvoke.call(pageObj, eventName) || {};
          shareParams.title = shareObj.title || params.title
          shareParams.desc = shareObj.desc || params.desc
          shareParams.path = shareObj.path ? utils.addHtmlSuffixToUrl(shareObj.path) : params.path
          shareParams.path.length > 0 && "/" === shareParams.path[0] && (shareParams.path = shareParams.path.substr(1))
          shareParams.success = shareObj.success
          shareParams.cancel = shareObj.cancel
          shareParams.fail = shareObj.fail
          shareParams.complete = shareObj.complete
      }
      return shareParams;
  };
  wx.onAppRoute(utils.surroundByTryCatch(function(params) {
      var path = params.path,
          webviewId = params.webviewId,
          query = params.query || {},
          openType = params.openType;
      skipPage(path, webviewId, query, openType);
  }), "onAppRoute");
  
  wx.onWebviewEvent(utils.surroundByTryCatch(function(params) {
      var webviewId = params.webviewId,
          eventName = params.eventName,
          data = params.data;
      return doWebviewEvent(webviewId, eventName, data);
  },"onWebviewEvent"));
  
  ServiceJSBridge.on("onPullDownRefresh", utils.surroundByTryCatch(function(e, pWebViewId) {
      pullDownRefresh(pWebViewId);
  },"onPullDownRefresh"));
  
  var shareAppMessage = function(params, webviewId) {
      var shareInfo = invokeShareAppMessage(params, webviewId);
      ServiceJSBridge.invoke("shareAppMessage", shareInfo, function(res) {
          / ^shareAppMessage: ok /.test(res.errMsg) &&
          "function" == typeof shareInfo.success ?
              shareInfo.success(res) :
              /^shareAppMessage:cancel/.test(res.errMsg) && "function" == typeof shareInfo.cancel ?
                  shareInfo.cancel(res) :
                  /^shareAppMessage:fail/.test(res.errMsg) && "function" == typeof shareInfo.fail && shareInfo.fail(res),//bug?? 原代码：shareInfo.fail && shareInfo.cancel(res)
          "function" == typeof shareInfo.complete && shareInfo.complete(res)
      });
  };
  
  ServiceJSBridge.on("onShareAppMessage", utils.surroundByTryCatch(shareAppMessage, "onShareAppMessage"));
  reset = function() {
      currentPage = undefined;
      pageStackObjs = {};
      pageRegObjs = {};
      pageStack = [];
      pageIndex = 0;
  };
  setWxConfig = function(e) {
      __wxConfig__ = e;
  };
  setWxRoute = function(e) {
      __wxRoute = e;
  };
  setWxRouteBegin = function(e) {
      __wxRouteBegin = e;
  };
  getWebviewIdToPage = function() {
      return pageStackObjs;
  };
  getRouteToPage = function() {
      return pageRegObjs;
  };
  
  export default {
      getRouteToPage,
      getWebviewIdToPage,
      setWxRouteBegin,
      setWxRoute,
      setWxConfig,
      reset,
      pageHolder,
      getCurrentPages,
      getCurrentPage
  }