/**
 * 校验参数工具
 * 
 */

import { ERRORENUM } from "../config/errorEnum";
import { BizError } from "./bizError";

/**
 * 通过config校验表单参数param
 * 包括类型 String, Number, Boolean, [Number], [Object]
 * 参数是必填
 * 方法会校验表单中存在的多余字段
 * todo 后续优化配置
 * @param name 被调用的方法名
 * @param config 校验配置
 * @param param 需要校验的参数
 * @returns true 无需关注返回
 */
export function eccFormParam(name:string, keyTypeConf:object, param:object) {
    for (let key in keyTypeConf ) {
        let {type, notMustHave} = keyTypeConf[key];

        let isError = false; //校验是否异常
        let errorStr = "";//异常说明

        if ( (typeof param[key] != 'boolean' && !param[key] ) ) {
            if (!notMustHave) { 
                isError = true;
                errorStr = `缺失${key}字段`;
            }
        } else if (param[key]) {
            let paramType = typeof param[key];
            let confType = keyTypeConf[key].type;
            switch(confType) {
                case 'Number':
                    if ( paramType != 'number' )  {
                        isError = true;
                    } else {
                        if ((""+param[key]).indexOf('.') > -1) {
                            param[key] = parseInt(`${param[key] *100}`)/100;
                        }
                    }
                break;
                case 'String':
                    if ( paramType != 'string' ) isError = true;
                break;
                case 'Boolean':
                    if ( paramType != 'boolean' ) isError = true;
                break;
                case '[Number]':
                    if ( !Array.isArray(param[key]) ) isError = true;
                    for (let i =0; i <  param[key].length; i++) {
                        let item = param[key][i];
                        if ( typeof item != 'number' ) {
                            isError = true;
                            errorStr = `${key}应是number型数组其中下标${i}是${typeof item}`;
                        }
                    }
                break;
                case '[Object]':
                    if ( !Array.isArray(param[key]) ) isError = true;
                    for (let i =0; i <  param[key].length; i++) {
                        let item = param[key][i];
                        if ( typeof item != 'object' ) {
                            isError = true;
                            errorStr = `${key}应是object型数组其中下标${i}是${typeof item}`;
                        }
                    }
                break;
            }
            errorStr = isError && errorStr == "" ? `${key}应该是${type}型 而不是${paramType}`: errorStr;
            
        }
       
        if ( isError ) throw new BizError(ERRORENUM.表单校验失败, name, errorStr);
    }
    /**判断多余的参数 */
    for (let key in param) {
        if (!keyTypeConf[key]) throw new BizError(ERRORENUM.表单校验失败, name, `多余${key}字段`);
    }
    return true;
}


/**
 * 根据conf配置校验请求参数
 * @param conf 配置
 * @param param 表单
 * @param skipKeys []不必填的字段
 */
export function eccReqParamater(conf:object, param, skipKeys?) {
    skipKeys = skipKeys || [];
    for (let key in conf) {
        let type = conf[key];
        let value = param[key];

        let isError = false; //校验是否异常
        let errorStr = "";//异常说明

        if ( (typeof value != 'boolean') && !value ) {
            if (skipKeys.indexOf(key) < 0 ) {
                isError = true;
                errorStr = `缺少 ${key} 字段`;
            }
        } else if(param[key]) {
            let paramType = typeof param[key];
            switch(conf[key]) {
                case 'Number':
                    if ( paramType != 'number' )  {
                        isError = true;
                    }
                break;
                case 'String':
                    if ( paramType != 'string' ) isError = true;
                break;
                case 'Boolean':
                    if ( paramType != 'boolean' ) isError = true;
                break;
                case '[Number]':
                    if ( !Array.isArray(param[key]) ) isError = true;
                    for (let i =0; i <  param[key].length; i++) {
                        let item = param[key][i];
                        if ( typeof item != 'number' ) {
                            isError = true;
                            errorStr = `${key}应是number型数组其中下标${i}是${typeof item}`;
                        }
                    }
                break;
                case '[Object]':
                    if ( !Array.isArray(param[key]) ) isError = true;
                    for (let i =0; i <  param[key].length; i++) {
                        let item = param[key][i];
                        if ( typeof item != 'object' ) {
                            isError = true;
                            errorStr = `${key}应是object型数组其中下标${i}是${typeof item}`;
                        }
                    }
                break;
            }
            errorStr = isError && errorStr == "" ? `${key}应该是${type}型 而不是${paramType}`: errorStr;
        }

        if (isError) throw new BizError(ERRORENUM.参数错误, errorStr);
        
    }
    for (let key in param) {
        if (!conf[key]) throw new BizError(ERRORENUM.参数错误, `多余${key}字段`);
    }
    return param;
}
