/**
 * 科拓非标API模块
 */

import { logger } from "mslib"
import { ApiResponse } from "./KTApiCommon"
import { CryptoUtils } from "./CryptoUtils"
import { ParamDecryptFailedError, ParamEmptyError, ParamError } from "./Errors"
import Contants from "./Contants";
import { getBasicConfig, getNonStandardApiConfig } from "./Config";

/**
 * 请求基类
 */
export class ApiRequestBase {
    parkId: any;
}

const defaults = {
    key: 'Keytop:1234567812345678!',
    iv: '20210723'
}

const des3Config = Object.assign(defaults, getNonStandardApiConfig()?.des3);
logger.trace(`des3Config:`, des3Config);

/**
 * 非标API装饰器
 * 
 * 自动解密，异常捕获，日志记录，发生异常自动返回异常报文等
 * @param description 服务描述
 * @returns
 */
export function Service(description?: string): MethodDecorator {
    return function (target: Object, propertyKey: string, descriptor: PropertyDescriptor) {
        logger.info(`${Contants.SS_SERVICE_BASE_URL}${getBasicConfig()?.projectId}.${target.constructor.name}/1.0`, description);

        let method = descriptor.value;

        descriptor.value = async function (...args) {
            let response;
            let _error;

            try {
                if (!Contants.IS_DEBUG) {
                    if (!args || !args[0]?.data) throw new ParamEmptyError();

                    let plaintext;
                    try {
                        plaintext = CryptoUtils.des3DecryCode(args[0].data, des3Config.key, des3Config.iv);
                    } catch (error) {
                        throw new ParamDecryptFailedError();
                    }

                    //解密成功后删除密文
                    delete args[0].data;

                    Object.assign(args[0], JSON.parse(plaintext));
                }

                response = await method.apply(this, args);
            } catch (error) {
                if (error instanceof ParamError) response = ApiResponse.failed(error.message);
                else if (typeof error === 'string') response = ApiResponse.failed(error);
                else response = ApiResponse.failed('服务器异常');

                _error = error;
            }

            logger[_error ? 'error' : 'info'](`${target.constructor.name},input:${JSON.stringify(args, logInputJSONReplacer)},response:${JSON.stringify(response)}`, _error);

            return response;
        }
    }
}

/**
 * input 日志记录 JSON replacer
 * 
 * 过滤前端传过来的base64图片字符串
 * @param key 
 * @param value 
 * @returns 
 */
function logInputJSONReplacer(key, value) {
    if (typeof value === 'string' && value.startsWith('data:')) return 'base64Str';

    return value;
}