"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var path = tslib_1.__importStar(require("path"));
var fs = tslib_1.__importStar(require("fs-extra"));
var ajv_1 = tslib_1.__importDefault(require("ajv"));
var chalk_1 = tslib_1.__importDefault(require("chalk"));
var init_1 = require("../init");
var formatSchema = function (schema) {
    return JSON.parse(JSON.stringify(schema).replace(/"#\/definitions/g, '"definitions#/definitions'));
};
exports.getAJV = (function () {
    var inst;
    var lastSwagger;
    return function (swagger) {
        if (lastSwagger === swagger && inst) {
            return inst;
        }
        lastSwagger = swagger;
        inst = new ajv_1.default();
        inst.addFormat('int32', function (d) {
            return !!d.match(/^[0-9-]+$/);
        });
        var definitions = getDefinitions(swagger);
        if (definitions) {
            inst.addSchema({
                $id: 'definitions',
                definitions: formatSchema(definitions)
            });
        }
        return inst;
    };
})();
function getSwagger(basePath) {
    var swaggerPath = path.join(init_1.SmTmpDir, init_1.basePathToFileName((basePath || init_1.DefaultBasePath) + ".json"));
    if (fs.existsSync(swaggerPath)) {
        var swagger = require(swaggerPath);
        var state = fs.statSync(swaggerPath);
        if (swagger.__mtime && swagger.__mtime !== state.mtime) {
            delete require.cache[require.resolve(swaggerPath)];
            swagger = require(swaggerPath);
        }
        swagger.__mtime = state.mtime;
        return swagger;
    }
    else {
        throw Error('物料文件不存在，请重新生成');
    }
}
exports.getSwagger = getSwagger;
function getDefinitions(swagger) {
    var definitions = swagger.definitions;
    return definitions;
}
exports.getDefinitions = getDefinitions;
function getPath(swagger, path) {
    var paths = swagger.paths;
    var matched = paths[path];
    if (!matched) {
        throw Error("\u63A5\u53E3 \"" + path + "\" \u4E0D\u5B58\u5728");
    }
    return matched;
}
exports.getPath = getPath;
function getParamSchema(parameters) {
    var paramsSchema = {
        type: 'object',
        properties: {}
    };
    return parameters.reduce(function (parentSchema, param) {
        var _a = param.in, paramType = _a === void 0 ? '' : _a, schema = param.schema, _b = param.name, name = _b === void 0 ? '' : _b, type = param.type, required = param.required, description = param.description, format = param.format;
        if (parentSchema.properties) {
            var cur = parentSchema.properties[paramType];
            if (schema) {
                parentSchema.properties[paramType] = formatSchema(schema);
            }
            else {
                if (!cur) {
                    cur = parentSchema.properties[paramType] = {
                        type: 'object'
                    };
                }
                if (!cur.properties) {
                    cur.properties = {};
                }
                cur.properties[name] = {
                    type: type,
                    required: required ? ["" + required] : required,
                    description: description,
                    format: format
                };
            }
        }
        return parentSchema;
    }, paramsSchema);
}
exports.getParamSchema = getParamSchema;
exports.validatorFactory = function (ajv) { return function (shema, data) {
    return ajv.validate(shema, data) ? '' : ajv.errorsText(ajv.errors);
}; };
exports.defaultValidator = function (_a) {
    var code = _a.code, message = _a.message, result = _a.result;
    return tslib_1.__awaiter(void 0, void 0, void 0, function () {
        var url, _b, basePath, path, send, _c, body, status, baseInfo, swagger, validator, method, matchMethod, parameters, responses, error, schema, error;
        return tslib_1.__generator(this, function (_d) {
            url = result.req.url, _b = result.swagger, basePath = _b.basePath, path = _b.path, send = result.send, _c = result.receive, body = _c.body, status = _c.status;
            baseInfo = path + "/" + url;
            try {
                if (code) {
                    throw Error("\u63A5\u53E3 " + baseInfo + " \u521D\u59CB\u5316\u51FA\u9519: " + message);
                }
                else {
                    swagger = getSwagger(basePath);
                    validator = exports.validatorFactory(exports.getAJV(swagger));
                    method = (send ? send.method : 'GET').toLocaleLowerCase();
                    matchMethod = getPath(swagger, path)[method];
                    if (!matchMethod) {
                        throw Error("\u63A5\u53E3 " + baseInfo + " \u4E0D\u652F\u6301 " + method);
                    }
                    parameters = matchMethod.parameters, responses = matchMethod.responses;
                    if (parameters.length && send) {
                        error = validator(getParamSchema(parameters), send);
                        if (error) {
                            console.log(chalk_1.default.red("\u63A5\u53E3 " + baseInfo + " \u53C2\u6570\u4E0D\u7B26\u5408\u7EA6\u5B9A: " + error));
                        }
                        else {
                            console.log(chalk_1.default.red("\u63A5\u53E3 " + baseInfo + " \u53C2\u6570\u7B26\u5408\u7EA6\u5B9A"));
                        }
                    }
                    schema = responses[status].schema;
                    if (schema) {
                        error = validator(formatSchema(schema), body);
                        if (error) {
                            console.log(chalk_1.default.red("\u63A5\u53E3 " + baseInfo + " \u6570\u636E\u8FD4\u56DE\u4E0D\u7B26\u5408\u7EA6\u5B9A: " + error));
                        }
                        else {
                            console.log(chalk_1.default.green("\u63A5\u53E3 " + baseInfo + " \u6570\u636E\u8FD4\u56DE\u7B26\u5408\u7EA6\u5B9A"));
                        }
                    }
                    else if (body) {
                        throw Error("\u63A5\u53E3 " + baseInfo + " \u4E0D\u5E94\u8BE5\u6709\u6570\u636E\u8FD4\u56DE");
                    }
                }
            }
            catch (e) {
                console.log(chalk_1.default.red(e.message));
            }
            return [2 /*return*/];
        });
    });
};
//# sourceMappingURL=validator.js.map