/**
 * JIT_GW_ExtInterface 模块，提供与客户端交互的功能
 */
class CA_ExtInterface {
  constructor() {
    this.currentSessionWSURL = '';
    this.useActioveX = false;
    this.options = {};
    this.webSocket = null;
    this.init();
  }

  /**
     * 简单的 Object.assign 兼容 IE <= 11 的 polyfill
     * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
     * @param {Object} target - 目标对象
     * @param {Object} options - 新的选项对象
     */
  extendOptions(target, options) {
    if (typeof Object.assign === 'function') {
      Object.assign(target, options);
    } else {
      // 兼容 IE < 11
      for (const key in options) {
        target[key] = options[key];
      }
    }
  }

  /**
     * 检查当前会话的 WebSocket URL
     */
  checkSessionWSURL() {
    if (this.currentSessionWSURL === '') {
      if (document.location.protocol === 'https:') {
        this.currentSessionWSURL = this.sendAndWaitMessage('https://127.0.0.1:10087/', 'QueryService');
      } else {
        this.currentSessionWSURL = this.sendAndWaitMessage('http://127.0.0.1:10086/', 'QueryService');
      }
    }
  }

  /**
     * 检查是否使用 ActiveX
     */
  isUseActioveX() {
    if (!!window.ActiveXObject || 'ActiveXObject' in window) {
      this.useActioveX = true;
    } else {
      this.useActioveX = false;
    }
  }

  /**
     * 扩展发送消息并等待响应
     * @param {string} operatorCmd - 操作命令
     * @param {string} sendMsg - 发送的消息
     * @returns {string} 响应消息
     */
  async sendAndWaitMessageEx(operatorCmd, sendMsg) {
    await this.checkSessionWSURL();
    const strSendMsg = operatorCmd + ':' + sendMsg;
    return this.sendAndWaitMessage(this.currentSessionWSURL, strSendMsg);
  }

  /**
     * 发送消息并等待响应
     * @param {string} wsurl - WebSocket URL
     * @param {string} sendMsg - 发送的消息
     * @returns {string} 响应消息
     */
  sendAndWaitMessage(wsurl, sendMsg) {
    let ResultMsg = '{"value":""}';
    if (ResultMsg === wsurl) {
      return;
    }
    try {
      const globalXmlHttpRequest = new XMLHttpRequest();
      globalXmlHttpRequest.open('POST', wsurl, false);
      globalXmlHttpRequest.setRequestHeader('Content-Type', 'text/plain;charset=UTF-8');
      globalXmlHttpRequest.send(sendMsg);
      ResultMsg = globalXmlHttpRequest.responseText;
      return ResultMsg;
    } catch (e) {
      this.currentSessionWSURL = '';
      if (this.options.onError) {
        this.options.onError.call(undefined, e);
      }
    }
  }

  /**
     * 配置选项
     * @param {Object} extendOption - 扩展选项
     */
  config(extendOption) {
    if (extendOption && typeof extendOption === 'object') {
      this.extendOptions(this.options, extendOption);
    }
  }

  /**
     * 初始化
     */
  init() {
    this.isUseActioveX();
  }

  /**
     * 返回客户端的版本
     * @returns {string} 客户端版本
     */
  getClientVersion() {
    if (this.useActioveX) {
      return window.PNXClient.GetClientVersion();
    } else {
      const result = JSON.parse(this.sendAndWaitMessageEx('GetClientVersion', ''));
      return result.value;
    }
  }

  /**
     * 下载客户端程序并安装
     * @param {string} bstrURL - 下载地址
     * @param {string} bstrHashValue - 哈希值
     * @param {boolean} bSync - 是否同步安装
     * @param {boolean} bOnlySSO - 是否仅安装 SSO
     * @returns {number} 安装结果
     */
  setupClient(bstrURL, bstrHashValue, bSync, bOnlySSO) {
    if (this.useActioveX) {
      return window.PNXClient.SetupClient(bstrURL, bstrHashValue, bSync, bOnlySSO);
    } else {
      const jsonstr = { 'strURL': bstrURL, 'strHashValue': bstrHashValue, 'bSync': bSync, 'bOnlySSO': bOnlySSO };
      const result = JSON.parse(this.sendAndWaitMessageEx('SetupClient', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * 获取硬件指纹信息
     * @param {number} dwSign - 签名
     * @param {string} strGateWayIP - 网关 IP
     * @returns {string} 硬件指纹信息
     */
  getFinger(dwSign, strGateWayIP) {
    if (this.useActioveX) {
      return window.PNXClient.GetFinger(dwSign, strGateWayIP);
    } else {
      const jsonstr = { 'dwSign': dwSign, 'strGateWayIP': strGateWayIP };
      const result = JSON.parse(this.sendAndWaitMessageEx('GetFinger', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * 设置转发策略和代填策略
     * @param {string} strProxyPolicy - 转发策略
     * @param {string} strSSOPolicy - 代填策略
     * @param {string} strGatewayAddress - 网关地址
     * @returns {number} 设置结果
     */
  setPolicy(strProxyPolicy, strSSOPolicy, strGatewayAddress) {
    if (this.useActioveX) {
      return window.PNXClient.SetPolicy(strProxyPolicy, strSSOPolicy, strGatewayAddress);
    } else {
      const jsonstr = { 'strProxyPolicy': strProxyPolicy, 'strSSOPolicy': strSSOPolicy, 'strGatewayAddress': strGatewayAddress };
      const result = JSON.parse(this.sendAndWaitMessageEx('SetPolicy', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * 启动认证信息模块
     * @param {string} strFileName - 文件名
     * @param {string} strXmlData - XML 数据
     * @returns {string} 认证信息
     */
  getAuthToken(strFileName, strXmlData) {
    if (this.useActioveX) {
      return window.PNXClient.GetAuthToken(strFileName, strXmlData);
    } else {
      const jsonstr = { 'strFileName': strFileName, 'strXmlData': strXmlData };
      const result = JSON.parse(this.sendAndWaitMessageEx('GetAuthToken', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * 打开 BS 应用
     * @param {string} strUrl - 应用 URL
     * @returns {number} 打开结果
     */
  navigateURL(strUrl) {
    if (this.useActioveX) {
      return window.PNXClient.NavigateURL(strUrl);
    } else {
      const jsonstr = { 'strUrl': strUrl };
      const result = JSON.parse(this.sendAndWaitMessageEx('NavigateURL', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * 打开 CS 应用
     * @param {string} strGatewayAddress - 网关地址
     * @param {string} strAppFlag - 应用标识
     * @param {string} strAppPath - 应用路径
     * @returns {number} 打开结果
     */
  executeCS(strGatewayAddress, strAppFlag, strAppPath) {
    if (this.useActioveX) {
      return window.PNXClient.ExecuteCS(strGatewayAddress, strAppFlag, strAppPath);
    } else {
      const jsonstr = { 'strGatewayAddress': strGatewayAddress, 'strAppFlag': strAppFlag, 'strAppPath': strAppPath };
      const result = JSON.parse(this.sendAndWaitMessageEx('ExecuteCS', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * 设置自动更新策略
     * @param {string} strGatewayAddress - 网关地址
     * @param {number} nGatewayPort - 网关端口
     * @param {string} strUserToken - 用户令牌
     * @param {number} updatedelay - 更新延迟
     * @returns {number} 设置结果
     */
  setUpdatePolicy(strGatewayAddress, nGatewayPort, strUserToken, updatedelay) {
    if (this.useActioveX) {
      return window.PNXClient.SetUpdatePolicy(strGatewayAddress, nGatewayPort, strUserToken, updatedelay);
    } else {
      const jsonstr = { 'strGatewayAddress': strGatewayAddress, 'nGatewayPort': nGatewayPort, 'strUserToken': strUserToken, 'ulUpdateDelay': updatedelay };
      const result = JSON.parse(this.sendAndWaitMessageEx('SetUpdatePolicy', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * 获取客户端 IP
     * @param {string} strGatewayIP - 网关 IP
     * @returns {string} 客户端 IP
     */
  getClientIP(strGatewayIP) {
    if (this.useActioveX) {
      return window.PNXClient.GetClientIP(strGatewayIP);
    } else {
      const jsonstr = { 'strGatewayIP': strGatewayIP };
      const result = JSON.parse(this.sendAndWaitMessageEx('GetClientIP', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * 登出网关
     * @param {string} strServerIP - 服务器 IP
     * @returns {number} 登出结果
     */
  gwLogout(strServerIP) {
    if (this.useActioveX) {
      return window.PNXClient.GWLogout(strServerIP);
    } else {
      const jsonstr = { 'strServerIP': strServerIP };
      const result = JSON.parse(this.sendAndWaitMessageEx('GWLogout', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * 运行安装包
     * @param {number} lRunType - 运行类型
     * @param {boolean} bIsOnlySSO - 是否仅安装 SSO
     * @returns {number} 运行结果
     */
  runSetup(lRunType, bIsOnlySSO) {
    if (this.useActioveX) {
      return window.PNXClient.RunSetup(lRunType, bIsOnlySSO);
    } else {
      const jsonstr = { 'lRunType': lRunType, 'bIsOnlySSO': bIsOnlySSO };
      const result = JSON.parse(this.sendAndWaitMessageEx('RunSetup', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * 获取下载进度
     * @returns {number} 下载进度
     */
  getDownloadProgress() {
    if (this.useActioveX) {
      return window.PNXClient.GetDownloadProgress();
    } else {
      const jsonstr = '';
      const result = JSON.parse(this.sendAndWaitMessageEx('GetDownloadProgress', jsonstr));
      return result.value;
    }
  }

  /**
     * 是否安装完成
     * @returns {boolean} 安装完成状态
     */
  isInstallComplete() {
    if (this.useActioveX) {
      return window.PNXClient.IsInstallComplete();
    } else {
      const jsonstr = '';
      const result = JSON.parse(this.sendAndWaitMessageEx('IsInstallComplete', jsonstr));
      return result.value;
    }
  }

  /**
     * 初始化签包对象
     * @param {string} strAlgType - 算法类型
     * @param {string} strAuxParam - 辅助参数
     * @returns {number} 初始化结果
     */
  initialize(strAlgType, strAuxParam) {
    if (this.useActioveX) {
      return window.PNXClient.Initialize(strAlgType, strAuxParam);
    } else {
      const jsonstr = { 'strAlgType': strAlgType, 'strAuxParam': strAuxParam };
      const result = JSON.parse(this.sendAndWaitMessageEx('Initialize', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * 设置摘要算法
     * @param {string} strDigestAlg - 摘要算法
     * @returns {number} 设置结果
     */
  setDigestAlg(strDigestAlg) {
    if (this.useActioveX) {
      return window.PNXClient.SetDigestAlg(strDigestAlg);
    } else {
      const jsonstr = { 'strDigestAlg': strDigestAlg };
      const result = JSON.parse(this.sendAndWaitMessageEx('SetDigestAlg', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * 设置单证书是否弹出对话框
     * @param {number} isChoose - 是否弹出对话框
     * @returns {number} 设置结果
     */
  setChooseSingleCert(isChoose) {
    if (this.useActioveX) {
      return window.PNXClient.SetChooseSingleCert(isChoose);
    } else {
      const jsonstr = { 'isChoose': isChoose };
      const result = JSON.parse(this.sendAndWaitMessageEx('SetChooseSingleCert', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * 添加证书过滤条件
     * @param {number} ulType - 过滤类型
     * @param {string} strValue - 过滤值
     * @returns {number} 添加结果
     */
  addFilter(ulType, strValue) {
    if (this.useActioveX) {
      return window.PNXClient.AddFilter(ulType, strValue);
    } else {
      const jsonstr = { 'ulType': ulType, 'strValue': strValue };
      const result = JSON.parse(this.sendAndWaitMessageEx('AddFilter', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * 清除所有过滤条件
     * @returns {number} 清除结果
     */
  clearFilter() {
    if (this.useActioveX) {
      return window.PNXClient.ClearFilter();
    } else {
      const jsonstr = '';
      const result = JSON.parse(this.sendAndWaitMessageEx('ClearFilter', jsonstr));
      return result.value;
    }
  }

  /**
     * P1 签名
     * @param {string} strValueBase64 - 待签名的 Base64 字符串
     * @returns {string} 签名结果
     */
  p1Sign(strValueBase64) {
    if (this.useActioveX) {
      return window.PNXClient.P1Sign(strValueBase64);
    } else {
      const jsonstr = { 'strValueBase64': strValueBase64 };
      const result = JSON.parse(this.sendAndWaitMessageEx('P1Sign', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * P1 签名字符串
     * @param {string} strValue - 待签名的字符串
     * @returns {string} 签名结果
     */
  p1SignString(strValue) {
    if (this.useActioveX) {
      return window.PNXClient.P1SignString(strValue);
    } else {
      const jsonstr = { 'strValue': strValue };
      const result = JSON.parse(this.sendAndWaitMessageEx('P1SignString', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * P7 签名
     * @param {string} strValueBase64 - 待签名的 Base64 字符串
     * @param {boolean} isDetach - 是否分离签名
     * @param {boolean} isIncludeCert - 是否包含证书
     * @returns {string} 签名结果
     */
  p7Sign(strValueBase64, isDetach, isIncludeCert) {
    if (this.useActioveX) {
      return window.PNXClient.P7Sign(strValueBase64, isDetach, isIncludeCert);
    } else {
      const jsonstr = { 'strValueBase64': strValueBase64, 'isDetach': isDetach, 'isIncludeCert': isIncludeCert };
      const result = JSON.parse(this.sendAndWaitMessageEx('P7Sign', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * P7 签名字符串
     * @param {string} strValue - 待签名的字符串
     * @param {boolean} isDetach - 是否分离签名
     * @param {boolean} isIncludeCert - 是否包含证书
     * @returns {string} 签名结果
     */
  p7SignString(strValue, isDetach, isIncludeCert) {
    if (this.useActioveX) {
      return window.PNXClient.P7SignString(strValue, isDetach, isIncludeCert);
    } else {
      const jsonstr = { 'strValue': strValue, 'isDetach': isDetach, 'isIncludeCert': isIncludeCert };
      const result = JSON.parse(this.sendAndWaitMessageEx('P7SignString', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * 释放签名对象
     * @returns {number} 释放结果
     */
  finalize() {
    if (this.useActioveX) {
      return window.PNXClient.Finalize();
    } else {
      const jsonstr = '';
      const result = JSON.parse(this.sendAndWaitMessageEx('Finalize', jsonstr));
      return result.value;
    }
  }

  /**
     * 获取签名版本
     * @returns {string} 签名版本
     */
  getSignVersion() {
    if (this.useActioveX) {
      return window.PNXClient.GetSignVersion();
    } else {
      const jsonstr = '';
      const result = JSON.parse(this.sendAndWaitMessageEx('GetSignVersion', jsonstr));
      return result.value;
    }
  }

  /**
     * 获取签名证书
     * @returns {string} 签名证书
     */
  getSignCert() {
    if (this.useActioveX) {
      return window.PNXClient.GetSignCert();
    } else {
      const jsonstr = '';
      const result = JSON.parse(this.sendAndWaitMessageEx('GetSignCert', jsonstr));
      return result.value;
    }
  }

  /**
     * 获取错误码
     * @returns {number} 错误码
     */
  getLastError() {
    if (this.useActioveX) {
      return window.PNXClient.GetLastError();
    } else {
      const jsonstr = '';
      const result = JSON.parse(this.sendAndWaitMessageEx('GetLastError', jsonstr));
      return result.value;
    }
  }

  /**
     * 获取错误信息
     * @returns {string} 错误信息
     */
  getLastErrorMessage() {
    if (this.useActioveX) {
      return window.PNXClient.GetLastErrorMessage();
    } else {
      const jsonstr = '';
      const result = JSON.parse(this.sendAndWaitMessageEx('GetLastErrorMessage', jsonstr));
      return result.value;
    }
  }

  /**
     * 销毁认证对象
     * @returns {number} 销毁结果
     */
  destoryAuth() {
    if (this.useActioveX) {
      return window.PNXClient.DestoryAuth();
    } else {
      const jsonstr = '';
      const result = JSON.parse(this.sendAndWaitMessageEx('DestoryAuth', jsonstr));
      return result.value;
    }
  }

  /**
     * 获取证书类型
     * @returns {string} 证书类型
     */
  getSignCertType() {
    if (this.useActioveX) {
      return window.PNXClient.GetSignCertType();
    } else {
      const jsonstr = '';
      const result = JSON.parse(this.sendAndWaitMessageEx('GetSignCertType', jsonstr));
      return result.value;
    }
  }

  /**
     * 获取签名摘要算法
     * @returns {string} 签名摘要算法
     */
  getSignHash() {
    if (this.useActioveX) {
      return window.PNXClient.GetSignHash();
    } else {
      const jsonstr = '';
      const result = JSON.parse(this.sendAndWaitMessageEx('GetSignHash', jsonstr));
      return result.value;
    }
  }

  /**
     * 使能调用序列
     * @param {boolean} bCallQueueEnable - 是否使能调用序列
     * @param {boolean} bHeadInfoEnable - 是否使能头部信息
     * @returns {number} 使能结果
     */
  callQueueEnable(bCallQueueEnable, bHeadInfoEnable) {
    if (this.useActioveX) {
      return window.PNXClient.CallQueueEnable(bCallQueueEnable, bHeadInfoEnable);
    } else {
      const jsonstr = { 'bCallQueueEnable': bCallQueueEnable, 'bHeadInfoEnable': bHeadInfoEnable };
      const result = JSON.parse(this.sendAndWaitMessageEx('CallQueueEnable', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * 清空调用序列结果
     * @returns {number} 清空调用序列结果
     */
  callQueueClear() {
    if (this.useActioveX) {
      return window.PNXClient.CallQueueClear();
    } else {
      const jsonstr = '';
      const result = JSON.parse(this.sendAndWaitMessageEx('CallQueueClear', jsonstr));
      return result.value;
    }
  }

  /**
     * 获取调用序列结果
     * @returns {string} 调用序列结果
     */
  callQueueGet() {
    if (this.useActioveX) {
      return window.PNXClient.CallQueueGet();
    } else {
      const jsonstr = '';
      const result = JSON.parse(this.sendAndWaitMessageEx('CallQueueGet', jsonstr));
      return result.value;
    }
  }

  /**
     * 客户端安全策略检查
     * @param {string} strGatewayAddress - 网关地址
     * @param {number} usGatewayPort - 网关端口
     * @param {string} strSecurityPolicys - 安全策略
     * @returns {boolean} 检查结果
     */
  doClientSecurityCheck(strGatewayAddress, usGatewayPort, strSecurityPolicys) {
    if (this.useActioveX) {
      return window.PNXClient.DoClientSecurityCheck(strGatewayAddress, usGatewayPort, strSecurityPolicys);
    } else {
      const jsonstr = { 'strGatewayAddress': strGatewayAddress, 'usGatewayPort': usGatewayPort, 'strSecurityPolicys': strSecurityPolicys };
      const result = JSON.parse(this.sendAndWaitMessageEx('DoClientSecurityCheck', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * 获取通讯协议版本
     * @returns {string} 通讯协议版本
     */
  getProtocolVersion() {
    if (this.useActioveX) {
      return window.PNXClient.GetProtocolVersion();
    } else {
      const jsonstr = '';
      const result = JSON.parse(this.sendAndWaitMessageEx('GetProtocolVersion', jsonstr));
      return result.value;
    }
  }

  /**
     * 修改 Key 的 Pin 码
     * @param {string} strCertSn - 证书序列号
     * @param {number} lPinCodeType - Pin 码类型
     * @param {string} strCurPinCode - 当前 Pin 码
     * @param {string} strNewPinCode - 新 Pin 码
     * @returns {number} 修改结果
     */
  changePinCode(strCertSn, lPinCodeType, strCurPinCode, strNewPinCode) {
    if (this.useActioveX) {
      return window.PNXClient.ChangePinCode(strCertSn, lPinCodeType, strCurPinCode, strNewPinCode);
    } else {
      const jsonstr = { 'strCertSn': strCertSn, 'lPinCodeType': lPinCodeType, 'strCurPinCode': strCurPinCode, 'strNewPinCode': strNewPinCode };
      const result = JSON.parse(this.sendAndWaitMessageEx('ChangePinCode', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * 等待策略设置完毕
     * @param {string} strGatewayAddress - 网关地址
     * @returns {number} 等待结果
     */
  waitSetPolicyFinish(strGatewayAddress) {
    if (this.useActioveX) {
      return window.PNXClient.WaitSetPolicyFinish(strGatewayAddress);
    } else {
      const jsonstr = { 'strGatewayAddress': strGatewayAddress };
      const result = JSON.parse(this.sendAndWaitMessageEx('WaitSetPolicyFinish', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * 获取会话 Token
     * @param {string} strGatewayAddress - 网关地址
     * @returns {string} 会话 Token
     */
  getSessionToken(strGatewayAddress) {
    if (this.useActioveX) {
      return window.PNXClient.GetSessionToken(strGatewayAddress);
    } else {
      const jsonstr = { 'strGatewayAddress': strGatewayAddress };
      const result = JSON.parse(this.sendAndWaitMessageEx('GetSessionToken', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * 获取控件版本
     * @returns {string} 控件版本
     */
  getVersion() {
    if (this.useActioveX) {
      return window.PNXClient.GetVersion();
    } else {
      const jsonstr = '';
      const result = JSON.parse(this.sendAndWaitMessageEx('GetVersion', jsonstr));
      return result.value;
    }
  }

  /**
     * 设置语言资源
     * @param {string} strLanguage - 语言资源
     * @returns {number} 设置结果
     */
  setLanguage(strLanguage) {
    if (this.useActioveX) {
      return window.PNXClient.SetLanguage(strLanguage);
    } else {
      const jsonstr = { 'strLanguage': strLanguage };
      const result = JSON.parse(this.sendAndWaitMessageEx('SetLanguage', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * 获取用户属性
     * @param {string} strGatewayAddress - 网关地址
     * @param {string} strAppFlag - 应用标识
     * @param {string} strAttributeName - 属性名称
     * @returns {string} 用户属性值
     */
  getAttribute(strGatewayAddress, strAppFlag, strAttributeName) {
    if (this.useActioveX) {
      return window.PNXClient.GetAttribute(strGatewayAddress, strAppFlag, strAttributeName);
    } else {
      const jsonstr = { 'strGatewayAddress': strGatewayAddress, 'strAppFlag': strAppFlag, 'strAttributeName': strAttributeName };
      const result = JSON.parse(this.sendAndWaitMessageEx('GetAttribute', JSON.stringify(jsonstr)));
      return result.value;
    }
  }

  /**
     * 获取签名加密 PIN 码
     * @returns {string} 签名加密 PIN 码
     */
  getPinCode() {
    if (this.useActioveX) {
      return window.PNXClient.GetPinCode();
    } else {
      const jsonstr = '';
      const result = JSON.parse(this.sendAndWaitMessageEx('GetPinCode', jsonstr));
      return result.value;
    }
  }
  /*
   *曙光四川CA
   *'SOF_GetUserList' 证书列表
   *'SOF_ExportUserCert' 导出证书
   *'SOF_GetCertInfo': 获取证书信息
   *'SOF_GenRandom': 生成随机数
   *'SOF_SignData': 获取证书签名
   *'SOF_Login': 登录证书
   *'SOF_GetPinRetryCount': 剩余次数
   */
  /**
   *
   * 获取webSocket消息
  * @returns {string}
   */
  getMessage({ action, params = [] }) {
    return new Promise((resolve, reject) => {
      var obj = JSON.stringify({
        'action': action,
        'params': params
      });
      if (!this.webSocket) {
        this.webSocket = new WebSocket('wss://localhost:36171');
        this.webSocket.onerror = (event) => {
          this.webSocket = null;
          reject(event);
        };
        this.webSocket.onopen = () => {
          this.webSocket.send(obj);
        };
      } else {
        this.webSocket.send(obj);
      }
      this.webSocket.onclose = (event) => {
        this.webSocket = null;
      };
      this.webSocket.onmessage = (event) => {
        resolve(JSON.parse(event.data));
      };
    });
  }
  /**
   *
   * base64解码
  * @returns {string} base64解码后的字符串
   */
  base64Decode(res) {
    let _keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
    let val = '';
    let chr1;
    let chr2;
    let chr3;
    let enc1;
    let enc2;
    let enc3;
    let enc4;
    let i = 0;
    res = res.replace(/[^A-Za-z0-9\+\/\=]/g, '');
    while (i < res.length) {
      enc1 = _keyStr.indexOf(res.charAt(i++));
      enc2 = _keyStr.indexOf(res.charAt(i++));
      enc3 = _keyStr.indexOf(res.charAt(i++));
      enc4 = _keyStr.indexOf(res.charAt(i++));
      chr1 = (enc1 << 2) | (enc2 >> 4);
      chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
      chr3 = ((enc3 & 3) << 6) | enc4;
      val = val + String.fromCharCode(chr1);
      if (enc3 !== 64) {
        val = val + String.fromCharCode(chr2);
      }
      if (enc4 !== 64) {
        val = val + String.fromCharCode(chr3);
      }
    }
    val = this.utf8_decode(val);
    return val;
  }
  /**
   *
   * base64编码
  * @returns {string} base64编码后的字符串
   */
  base64Encode(res) {
    let _keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
    let val = '';
    let chr1;
    let chr2;
    let chr3;
    let enc1;
    let enc2;
    let enc3;
    let enc4;
    let i = 0;
    res = this.utf8_encode(res);
    while (i < res.length) {
      chr1 = res.charCodeAt(i++);
      chr2 = res.charCodeAt(i++);
      chr3 = res.charCodeAt(i++);
      enc1 = chr1 >> 2;
      enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
      enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
      enc4 = chr3 & 63;
      if (isNaN(chr2)) {
        enc3 = enc4 = 64;
      } else if (isNaN(chr3)) {
        enc4 = 64;
      }
      val = val + _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4);
    }
    return val;
  }
  /**
   *
   * utf8解码
  * @returns {string} utf8解码后的字符串
   */
  utf8_decode(utftext) {
    let string = '';
    let i = 0;
    let c = 0;
    // let c1 = 0;
    let c2 = 0;
    let c3 = 0;
    while (i < utftext.length) {
      c = utftext.charCodeAt(i);
      if (c < 128) {
        string += String.fromCharCode(c);
        i++;
      } else if ((c > 191) && (c < 224)) {
        c2 = utftext.charCodeAt(i + 1);
        string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
        i += 2;
      } else {
        c2 = utftext.charCodeAt(i + 1);
        c3 = utftext.charCodeAt(i + 2);
        string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
        i += 3;
      }
    }
    return string;
  }
  /**
   *
   * utf8编码
  * @returns {string} utf8编码后的字符串
   */
  utf8_encode(string) {
    string = string.replace(/\r\n/g, '\n');
    var utftext = '';
    for (var n = 0; n < string.length; n++) {
      var c = string.charCodeAt(n);
      if (c < 128) {
        utftext += String.fromCharCode(c);
      } else if ((c > 127) && (c < 2048)) {
        utftext += String.fromCharCode((c >> 6) | 192);
        utftext += String.fromCharCode((c & 63) | 128);
      } else {
        utftext += String.fromCharCode((c >> 12) | 224);
        utftext += String.fromCharCode(((c >> 6) & 63) | 128);
        utftext += String.fromCharCode((c & 63) | 128);
      }

    }
    return utftext;
  }
}

const caPlugin = new CA_ExtInterface();
export default caPlugin;
