const system = require("../system");
const moment = require('moment')
const settings = require("../../config/settings");
const md5 = require("MD5");
const uuidv4 = require('uuid/v4');
class AppServiceBase {
  constructor() {
    this.restClient = system.getObject("util.restClient");
    this.execClient = system.getObject("util.execClient");
    this.cacheManager = system.getObject("db.common.cacheManager");
    this.pushlogSve = system.getObject("service.common.pushlogSve");
    this.pushlogFailType = { OLDRPC: 1, NEWRPC: 2, FAILLOG: 3, FQ: 4 };
    this.logCtl = system.getObject("service.common.oplogSve");
  }
  /**
   * 验证签名
   * @param {*} params 要验证的参数 
   * @param {*} app_key 应用的校验key
   */
  async verifySign(params, app_key) {
    if (!params) {
      return system.getResult(null, "请求参数为空");
    }
    if (!params.sign) {
      return system.getResult(null, "请求参数sign为空");
    }
    var signArr = [];
    var keys = Object.keys(params).sort();
    if (keys.length == 0) {
      return system.getResult(null, "请求参数信息为空");
    }
    for (let k = 0; k < keys.length; k++) {
      const tKey = keys[k];
      if (tKey != "sign" && params[tKey] && !(typeof (params[tKey]) === "object")) {
        signArr.push(tKey + "=" + params[tKey]);
      }
    }
    if (signArr.length == 0) {
      return system.getResult(null, "请求参数组装签名参数信息为空");
    }
    var resultSignStr = signArr.join("&") + "&key=" + app_key;
    var resultTmpSign = md5(resultSignStr).toUpperCase();
    if (params.sign != resultTmpSign) {
      return system.getResult(null, "返回值签名验证失败");
    }
    return system.getResultSuccess();
  }
  async restPostUrl(pobj, url) {
    try {
      var rtn = await this.restClient.execPost(pobj, url);
      if (!rtn || !rtn.stdout) {
        return system.getResult(null, "restPost data is empty");
      }
      var result = JSON.parse(rtn.stdout);
      return result;
    } catch (e) {
      var errorMsg = "error：" + e.stack;
      //日志记录
      this.logCtl.error({
        appid: pobj.appInfo ? pobj.appInfo.uapp_id || "" : "",
        appkey: pobj.appInfo ? pobj.appInfo.uapp_key || "" : "",
        requestId: pobj.requestId || "",
        op: "service/app.base.js/restPostUrl",
        content: errorMsg,
        // clientIp: pobj.clientIp,
        optitle: pobj.opType + "推送操作异常->restPostUrl",
      });
      return system.getResult(null, errorMsg);
    }
  }
  async restPostWithHValueUrl(pobj, url, hValue) {//curl请求带请求头信息
    try {
      if (!hValue) {
        hValue = "YLc6GsgLtuRGaVA5Om848x18NxLtHlyA";
      }
      var rtn = await this.restClient.execPostWithHValue(pobj, url, hValue);
      if (!rtn || !rtn.stdout) {
        return system.getResult(null, "execPostWithHValue data is empty");
      }
      var result = JSON.parse(rtn.stdout);
      return result;
    } catch (e) {
      var errorMsg = "error：" + e.stack;
      //日志记录
      this.logCtl.error({
        appid: pobj.appInfo ? pobj.appInfo.uapp_id || "" : "",
        appkey: pobj.appInfo ? pobj.appInfo.uapp_key || "" : "",
        requestId: pobj.requestId || "",
        op: "service/app.base.js/restPostWithHValueUrl",
        content: errorMsg,
        // clientIp: pobj.clientIp,
        optitle: pobj.opType + "推送操作异常->restPostWithHValueUrl",
      });
      return system.getResult(null, errorMsg);
    }
  }
  async restPostWithHAuthorizationUrl(pobj, userToken, url) {//curl请求带请求头信息
    try {
      var rtn = await this.restClient.restPostWithHAuthorizationUrl(userToken, url);
      if (!rtn || !rtn.stdout) {
        return system.getResult(null, "restPostWithHAuthorizationUrl data is empty");
      }
      var result = JSON.parse(rtn.stdout);
      return result;
    } catch (e) {
      var errorMsg = "error：" + e.stack;
      //日志记录
      this.logCtl.error({
        appid: pobj.appInfo ? pobj.appInfo.uapp_id || "" : "",
        appkey: pobj.appInfo ? pobj.appInfo.uapp_key || "" : "",
        requestId: pobj.requestId || "",
        op: "service/app.base.js/restPostWithHAuthorizationUrl",
        content: errorMsg,
        // clientIp: pobj.clientIp,
        optitle: pobj.opType + "推送操作异常->restPostWithHAuthorizationUrl",
      });
      return system.getResult(null, errorMsg);
    }
  }
  async execPostUrl(pobj, url) {
    try {
      var rtn = await this.execClient.execPost(pobj, url);
      if (!rtn || !rtn.stdout) {
        return system.getResult(null, "execPost data is empty");
      }
      var result = JSON.parse(rtn.stdout);
      return result;
    } catch (e) {
      var errorMsg = "error：" + e.stack;
      //日志记录
      this.logCtl.error({
        appid: pobj.appInfo ? pobj.appInfo.uapp_id || "" : "",
        appkey: pobj.appInfo ? pobj.appInfo.uapp_key || "" : "",
        requestId: pobj.requestId || "",
        op: "service/app.base.js/execPostUrl",
        content: errorMsg,
        // clientIp: pobj.clientIp,
        optitle: pobj.opType + "基类操作异常->execPostUrl",
      });
      return system.getResult(null, errorMsg);
    }
  }
  async opAliyunRpcVerifyParam(pobj) {//参数信息验证
    var verify = system.getResultSuccess();
    if (!pobj.interface_params) {
      verify = system.getResult(null, "interface_params can not be empty，100440");
    }
    var interface_params_info = JSON.parse(pobj.interface_params);
    if (!interface_params_info || !interface_params_info.action) {
      verify = system.getResult(null, "interface_params.action can not be empty，100443");
    }
    verify.data = interface_params_info;
    return verify;
  }
  /**
   * 阿里RPC调用
   * @param {*} pobj {action: rpcParam.action,reqbody: pobj.actionBody,rpcParam: rpcParam}
   * @param {*} params {为阿里的接口参数}
   */
  async opAliyunRpcReq(pobj, params) {
    try {
      // var action = obj.action;
      // var reqbody = obj.reqbody;
      // var rpcParam = obj.rpcParam;
      var aliyunClient = system.getObject("util.aliyunClient");
      var rtn = await aliyunClient.reqCustomByGet(params);
      return rtn;
    } catch (e) {
      var errorMsg = "error：" + e.stack;
      //日志记录
      this.logCtl.error({
        appid: pobj.appInfo ? pobj.appInfo.uapp_id || "" : "",
        appkey: pobj.appInfo ? pobj.appInfo.uapp_key || "" : "",
        requestId: pobj.requestId || "",
        op: "service/impl/utilsSve/opAliyunClientPost.js/opAliyunRpcReq",
        content: errorMsg,
        // clientIp: pobj.clientIp,
        optitle: pobj.opType + "推送操作异常->opAliyunRpcReq",
      });
      return system.getResult(null, errorMsg);
    }
  }
  // /**
  //   * 阿里RPC调用-post请求
  //   * @param {*} pobj {action: rpcParam.action,reqbody: pobj.actionBody,rpcParam: rpcParam}
  //   * @param {*} params {为阿里的接口参数}
  //   */
  // async opAliyunRpcReqByPost(pobj, params) {
  //   try {
  //     // var action = obj.action;
  //     // var reqbody = obj.reqbody;
  //     // var rpcParam = obj.rpcParam;
  //     var aliyunClient = system.getObject("util.aliyunClient");
  //     var rtn = await aliyunClient.reqCustomByPost(params);
  //     return rtn;
  //   } catch (e) {
  //     var errorMsg = "error：" + e.stack;
  //     //日志记录
  //     this.logCtl.error({
  //       appid: pobj.appInfo ? pobj.appInfo.uapp_id || "" : "",
  //       appkey: pobj.appInfo ? pobj.appInfo.uapp_key || "" : "",
  //       requestId: pobj.requestId || "",
  //       op: "service/impl/utilsSve/opAliyunClientPost.js/opAliyunRpcReqByPost",
  //       content: errorMsg,
  //       // clientIp: pobj.clientIp,
  //       optitle: pobj.opType + "推送操作异常->opAliyunRpcReqByPost",
  //     });
  //     return system.getResult(null, errorMsg);
  //   }
  // }
  /**
   * 处理成功后的信息
   * @param {*} pobj 
   * @param {*} result 
   * @param {*} opTitleDesc 
   * @param {*} failType this.pushlogFailType
   */
  async disposePushResult(pobj, result, opTitleDesc, failType) {//处理结果信息--内部使用
    var opType = pobj.opType || "";
    if (result.status != 0) {
      this.pushlogSve.createFailLogDb({
        appid: pobj.appInfo ? pobj.appInfo.uapp_id || "" : "",
        appkey: pobj.appInfo ? pobj.appInfo.uapp_key || "" : "",
        requestId: pobj.requestId || "",
        content: JSON.stringify(pobj),//推送的参数信息
        resultInfo: JSON.stringify(result),
        clientIp: pobj.clientIp || "",
        failType: failType || 3,
        opTitle: opType + "推送操作失败->" + opTitleDesc,
        pushNumber: pobj.pushNumber || 1
      });
      result.data = null;
      return result;
    }
    this.pushlogSve.createDb({
      appid: pobj.appInfo ? pobj.appInfo.uapp_id || "" : "",
      appkey: pobj.appInfo ? pobj.appInfo.uapp_key || "" : "",
      requestId: pobj.requestId || "",
      op: "推送业务类型：" + opType,
      content: JSON.stringify(pobj),//推送的参数信息
      resultInfo: JSON.stringify(result),
      returnType: '1',
      opTitle: opType + "数据推送成功->" + opTitleDesc
    });
    result.data = null;
    return result;
  }
  /**
   * 处理失败的结果信息--内部使用
   * @param {*} pobj 
   * @param {*} result 
   * @param {*} opTitleDesc 
   * @param {*} failType this.pushlogFailType
   */
  async disposePushResultFail(pobj, result, opTitleDesc, failType) {//处理失败的结果信息--内部使用
    var opType = pobj.opType || "";
    this.pushlogSve.createFailLogDb({
      appid: pobj.appInfo ? pobj.appInfo.uapp_id || "" : "",
      appkey: pobj.appInfo ? pobj.appInfo.uapp_key || "" : "",
      requestId: pobj.requestId || "",
      content: JSON.stringify(pobj),//推送的参数信息
      resultInfo: JSON.stringify(result),
      clientIp: pobj.clientIp || "",
      failType: failType || 3,
      opTitle: opType + "推送操作失败->" + opTitleDesc,
      pushNumber: pobj.pushNumber || 1
    });
    result.data = null;
    return result;
  }
  async getAliossjavaFileUrl(pobj, params) {//上传ali oss 文件调用
    var opType = pobj.opType || "";
    try {
      var aliOssFileInfo = await this.execPostUrl(params, settings.aliossjavaUrl());
      if (aliOssFileInfo == true) {
        var fileUrl = params.filedir + "/" + params.objectName;
        return system.getResultSuccess(fileUrl);
      }
      this.pushlogSve.createFailLogDb({
        appid: pobj.appInfo ? pobj.appInfo.uapp_id || "" : "",
        appkey: pobj.appInfo ? pobj.appInfo.uapp_key || "" : "",
        requestId: pobj.requestId || "",
        content: JSON.stringify(params),//推送的参数信息
        resultInfo: JSON.stringify(aliOssFileInfo),
        clientIp: pobj.clientIp || "",
        failType: 3,
        opTitle: opType + "aliossjava-upload阿里上传文件操作失败->getAliossjavaFileUrl",
        pushNumber: 1
      });
      return system.getResult(null, "java ali oss upload fail");
    } catch (e) {
      this.logCtl.error({
        appid: pobj.appInfo ? pobj.appInfo.uapp_id || "" : "",
        appkey: pobj.appInfo ? pobj.appInfo.uapp_key || "" : "",
        requestId: pobj.requestId || "",
        op: "service/app.base.js/getAliossjavaFileUrl",
        content: "error：" + e.stack,
        // clientIp: pobj.clientIp,
        optitle: pobj.opType || "" + "aliossjava-upload阿里上传文件操作异常->getAliossjavaFileUrl",
      });
      return system.getResult(-200, "java ali oss upload error");
    }
  }

  async opDownFileInfo(docUrl, result) {  //从oss下载到本地并上传到自己oss，之后删除本地文件
    /*docUrl下载链接，全路径，如：https://XXXXXX.pdf?XXXXX */
    try {
      var tmpFileName = docUrl.substring(0, docUrl.lastIndexOf("?"));
      var fileName = tmpFileName.substr(tmpFileName.lastIndexOf("/") + 1, tmpFileName.lenght);
      var fileType = tmpFileName.substr(tmpFileName.lastIndexOf(".") + 1, tmpFileName.lenght);
      //解码后的文件全名:xxx.pdf
      var fileAllName = decodeURIComponent(fileName);//为xxx.pdf
      var saveFilePath = '/tmp/' + fileAllName;
      // 下载文件到指定的路径
      var tmpp = await this.restClient.execDownload("'" + docUrl + "'", saveFilePath);
      //上传 saveFilePath的文件 到ossClient
      var uuid = uuidv4();
      var u = uuid.replace(/\-/g, "");
      var upFileName = "alifile_" + u + "." + fileType;
      var rtn = await this.ossClient.upfile(upFileName, saveFilePath);
      result.data = rtn;
      //删除本地文件
      fs.unlink(saveFilePath, function (err) { });
    } catch (e) {
      result.code = -200;
      result.message = "通过flowId获取到的文件url下载操作异常异常error";
      console.log(e.stack);
      //日志记录
      logCtl.error({
        optitle: "e签宝通过flowId获取到的文件url下载操作异常异常error",
        op: "base/service/impl/utilesignbaoSve/opDownFileInfo",
        content: "请求参数：docUrl=" + docUrl + "，异常信息error：" + e.stack,
        clientIp: ""
      });
    }
    return result;
  }

  async getOpInterfaceByProductId(appInfo, product_id) {//获取产品调用接口
    var getProductInterfaceUrl = settings.centerAppUrl() + "action/opProduct/springBoard";
    var getProductInterfaceObj = {
      "actionType": "getProductInterface",
      "appInfo": appInfo,
      "actionBody": { "product_id": product_id }
    };
    var productItemInterfaceResult = await this.restPostUrl(getProductInterfaceObj, getProductInterfaceUrl);
    return productItemInterfaceResult;
  }

  async getConvertSemiangleStr(str) {//去除空格及全角转半角
    var result = "";
    str = str.replace(/\s+/g, "");
    var len = str.length;
    for (var i = 0; i < len; i++) {
      var cCode = str.charCodeAt(i);
      //全角与半角相差（除空格外）：65248（十进制）
      cCode = (cCode >= 0xFF01 && cCode <= 0xFF5E) ? (cCode - 65248) : cCode;
      //处理空格
      cCode = (cCode == 0x03000) ? 0x0020 : cCode;
      result += String.fromCharCode(cCode);
    }
    return result;
  }
  /*
  返回20位业务订单号
  prefix：业务前缀
  */
  async getBusUid(prefix) {
    prefix = (prefix || "");
    if (prefix) {
      prefix = prefix.toUpperCase();
    }
    var prefixlength = prefix.length;
    var subLen = 8 - prefixlength;
    var uidStr = "";
    if (subLen > 0) {
      uidStr = await this.getUidInfo(subLen, 60);
    }
    var timStr = moment().format("YYYYMMDDHHmm");
    return prefix + timStr + uidStr;
  }
  /*
  len：返回长度
  radix：参与计算的长度，最大为62
  */
  async getUidInfo(len, radix) {
    var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');//长度62，到yz长度为长36
    var uuid = [], i;
    radix = radix || chars.length;
    if (len) {
      for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
    } else {
      var r;
      uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
      uuid[14] = '4';
      for (i = 0; i < 36; i++) {
        if (!uuid[i]) {
          r = 0 | Math.random() * 16;
          uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
        }
      }
    }
    return uuid.join('');
  }
  getUUID() {
    var uuid = uuidv4();
    var u = uuid.replace(/\-/g, "");
    return u;
  }
}
module.exports = AppServiceBase;
