import extsdk, { base64Util } from '@hyext/ext-sdk-basic';
import { Taf } from './libwup';
import obj from '../utils/obj';

/**
 * Wup信息 序列化
 * @param {Taf.Wup} data 
 * @returns {string}
 */
export function wupSerialize(data) {
  return obj.serialize(data, ['status.value', 'iVersion', 'iMessageType', 'iTimeout', 'cPacketType'])
}

/**
 * Wup 消息加密
 * @param {string} serventName 加密方法名
 * @param {Function} func 加密方法
 * @param {any} data 加密数据
 * @returns {string} 加密消息
 */
export function wupEncode(serventName, func, data) {
  const wup = new Taf.Wup();
  wup.setServant(serventName);
  wup.setFunc(func);
  wup.writeStruct("tReq", data);
  const outputStream = wup.encode();
  const arrayBuffer = outputStream.getBuffer();
  return base64Util.encode(arrayBuffer);
}

/**
 * @typedef {Object} DecodeInfo
 * @property {Taf.Wup} buffer 读取的流信息
 * @property {Object} rsp 读取结果
 * @property {number} bcode code
 */
/**
 * Wup 消息解析
 * @param {string} base64Str 解析base64字符串
 * @param {Function} ParseClass 解析类
 * @returns {DecodeInfo}
 */
export function wupDecode(base64Str, ParseClass, readCode) {
  let wup, rspStruct, code = 0;
  try {
    // base64解码
    const arrayBuffer = base64Util.decode(base64Str)

    // wup解码
    wup = new Taf.Wup()
    wup.decode(arrayBuffer)

    if (readCode) {
      code = wup.readInt32('')
    }

    // key校验
    const key = (wup.newdata.get('tRsp') && 'tRsp') || (wup.newdata.get('tResp') && 'tResp')
    if (!key) {
      throw new Error('Unavailable Response: unfound key tRsp or tResp')
    }

    // 用RspClass解析
    rspStruct = new ParseClass();
    wup.readStruct(key, rspStruct, ParseClass)

    return {
      buffer: wup,
      rsp: rspStruct,
      bcode: code,
    }
  } catch (err) {
    // 返回错误信息
    // err.message = `${err.message}|${wupSerialize(wup)}`;
    err.serialize = `${wupSerialize(wup)}`
    err.response = {
      buffer: wup,
      rsp: rspStruct,
      rspstr: base64Str,
      bcode: code,
    }
    throw err
  }
}