import { ENCRYPT_KEY, ENCRYPT_IV } from '@consts';
import { genCode } from 'app/pubUtils/util';
import { Context } from 'egg';
const crypto = require('crypto');
const isJSON = require('koa-is-json');

function aesEncrypt(data, key, iv) {
  const cipher = crypto.createCipheriv('aes-192-cbc', key, iv);
  let crypted = cipher.update(data, 'utf8', 'hex');
  crypted += cipher.final('hex');
  return crypted;
}

function aesDecrypt(data, key, iv) {
  const decipher = crypto.createDecipheriv('aes-192-cbc', key, iv);
  let decrypted = decipher.update(data, 'hex', 'utf8');
  decrypted += decipher.final('utf8');
  return decrypted;
}

module.exports = options => {
  return async function parmsDecode(ctx: Context, next) {
    let m = ctx.request.url.indexOf("/dev");
    let n = ctx.request.url.indexOf("/web");
    ctx.logcode = genCode(10);
    if(m == 0 || n == 0) {
      await next();
      return;
    } 
    if (options.threshold && ctx.length < options.threshold) return;
    const reqBody = ctx.request.body;

    if (isJSON(reqBody)) {
      const encodeStr = aesEncrypt(JSON.stringify(reqBody), ENCRYPT_KEY, ENCRYPT_IV);
      console.log(`encoded str: ${encodeStr}`);
    }

    console.log(ctx.app.config.decodeParm)
    if(ctx.app.config.decodeParm == false) {
      await next();
      return;
    }


    if (!reqBody.data) return;

    const decodeStr = aesDecrypt(reqBody.data, ENCRYPT_KEY, ENCRYPT_IV);
    ctx.logger.debug('decoded str:', decodeStr);
    try {
      ctx.request.body = JSON.parse(decodeStr);
      console.log('req body', ctx.request.body);
      ctx.service.utils.log('INFO', `[${ctx.request.url}] [${ctx.logcode}] request: ${JSON.stringify(ctx.request.body)}`)
    } catch (e) {
      console.error('parms parse err');
      ctx.service.utils.log('ERROR', `[${ctx.request.url}] [${ctx.logcode}] request: parms parse err`)

    }

    try{
      await next();
    } catch(e) {
      ctx.service.utils.log('ERROR', `[${ctx.request.url}] [${ctx.logcode}] err: ${e.stack}`);
      throw e;
    }
    const resBody = ctx.body;
    console.log('return value:', JSON.stringify(resBody));
    if (isJSON(resBody)) {
      ctx.body = { result: aesEncrypt(JSON.stringify(resBody), ENCRYPT_KEY, ENCRYPT_IV) };
      ctx.service.utils.log('INFO', `[${ctx.request.url}] [${ctx.logcode}] res: ${JSON.stringify(resBody)}`)
    } else {
      ctx.body = { result: aesEncrypt(JSON.stringify({ status: 3, data: 'internal err' }), ENCRYPT_KEY, ENCRYPT_IV) };
      ctx.service.utils.log('ERROR', `[${ctx.request.url}] [${ctx.logcode}] res: ${resBody}`)
    }
  };
};

