"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var _ = tslib_1.__importStar(require("lodash"));
// @ts-ignore
var easy_json_schema_1 = tslib_1.__importDefault(require("easy-json-schema")); // @fix module.exports = ejs;
var JSON5 = tslib_1.__importStar(require("json5"));
function yapiJSon2swagger(list, yapiConfig) {
    if (yapiConfig === void 0) { yapiConfig = {}; }
    var basePath = '';
    var info = {
        title: 'unknown',
        version: 'last',
        description: 'unknown'
    };
    var tags = [];
    var _a = yapiConfig.categoryMap, categoryMap = _a === void 0 ? function (s) { return s; } : _a, bodyJsonRequired = yapiConfig.bodyJsonRequired, required = yapiConfig.required;
    list.forEach(function (t) {
        if (t.proBasepath) {
            basePath = t.proBasepath;
        }
        if (t.proName)
            info.title = t.proName;
        if (t.proDescription)
            info.description = t.proDescription;
        var name = typeof categoryMap === 'function' ? categoryMap(t.name) : categoryMap[t.name] || t.name;
        tags.push({
            name: name,
            description: t.desc || t.name
        });
        t.name = name;
    });
    var reg = basePath ? new RegExp("^" + basePath) : undefined;
    var swaggerObj = {
        swagger: '2.0',
        info: info,
        basePath: basePath,
        tags: tags,
        schemes: [
            'http' // Only http
        ],
        paths: (function () {
            var apisObj = {};
            var _loop_1 = function (category) {
                var _loop_2 = function (api) {
                    // list of api
                    var url = reg ? api.path.replace(reg, '') : api.path;
                    if (apisObj[url] == null) {
                        apisObj[url] = {};
                    }
                    var method = api.method.toLowerCase();
                    apisObj[url][method] = (function () {
                        // eslint-disable-next-line @typescript-eslint/no-object-literal-type-assertion
                        var apiItem = {};
                        apiItem['tags'] = [category.name];
                        apiItem['summary'] = api.title;
                        apiItem['description'] = api.markdown;
                        switch (api.req_body_type) {
                            case 'form':
                            case 'file':
                                apiItem['consumes'] = ['multipart/form-data']; // form data required
                                break;
                            case 'json':
                                apiItem['consumes'] = ['application/json'];
                                break;
                            case 'raw':
                                apiItem['consumes'] = ['text/plain'];
                                break;
                            default:
                                break;
                        }
                        apiItem['parameters'] = (function () {
                            var paramArray = [];
                            for (var _i = 0, _a = api.req_headers; _i < _a.length; _i++) {
                                var p = _a[_i];
                                // Headers parameters
                                // swagger has consumes proprety, so skip proprety "Content-Type"
                                if (p.name === 'Content-Type') {
                                    continue;
                                }
                                paramArray.push({
                                    name: p.name,
                                    in: 'header',
                                    description: p.name + " (Only:" + p.value + ")",
                                    required: Number(p.required) === 1,
                                    type: 'string',
                                    default: p.value
                                });
                            }
                            for (var _b = 0, _c = api.req_params; _b < _c.length; _b++) {
                                var p = _c[_b];
                                // Path parameters
                                paramArray.push({
                                    name: p.name,
                                    in: 'path',
                                    description: p.desc,
                                    required: true,
                                    type: 'string' // always be type string
                                });
                            }
                            for (var _d = 0, _e = api.req_query; _d < _e.length; _d++) {
                                var p = _e[_d];
                                // Query parameters
                                paramArray.push({
                                    name: p.name,
                                    in: 'query',
                                    required: Number(p.required) === 1,
                                    description: p.desc,
                                    type: 'string' // always be type string
                                });
                            }
                            // @IMP: get 不能有 body
                            if (method !== 'get') {
                                switch (api.req_body_type // Body parameters
                                ) {
                                    case 'form': {
                                        for (var _f = 0, _g = api.req_body_form; _f < _g.length; _f++) {
                                            var p = _g[_f];
                                            paramArray.push({
                                                name: p.name,
                                                in: 'formData',
                                                required: Number(p.required) === 1,
                                                description: p.desc,
                                                type: p.type === 'text' ? 'string' : 'file' // in this time .formData type have only text or file
                                            });
                                        }
                                        break;
                                    }
                                    case 'json': {
                                        if (api.req_body_other) {
                                            var jsonParam = JSON5.parse(api.req_body_other);
                                            if (jsonParam !== null) {
                                                if (!jsonParam['type']) {
                                                    // required
                                                    if (bodyJsonRequired) {
                                                        jsonParam = JSON.parse(JSON.stringify(jsonParam).replace(/"([^*"]+":)/g, function (all, name) { return "\"*" + name; }));
                                                    }
                                                    jsonParam = easy_json_schema_1.default(jsonParam);
                                                }
                                                var name_1 = _.flow(_.camelCase, _.upperFirst)(url.replace(/\//g, '-') + 'Body'); // 向下兼容: 请勿修改 name 生成个规则
                                                if (jsonParam['title'] &&
                                                    jsonParam['title'].indexOf('empty object') !== -1) {
                                                    jsonParam['title'] = name_1;
                                                }
                                                paramArray.push({
                                                    name: name_1,
                                                    in: 'body',
                                                    description: jsonParam.description,
                                                    schema: jsonParam // as same as swagger's format
                                                });
                                            }
                                        }
                                        break;
                                    }
                                    case 'file': {
                                        paramArray.push({
                                            name: 'upfile',
                                            in: 'formData',
                                            description: api.req_body_other,
                                            type: 'file'
                                        });
                                        break;
                                    }
                                    case 'raw': {
                                        paramArray.push({
                                            name: 'raw',
                                            in: 'body',
                                            description: 'raw paramter',
                                            schema: {
                                                type: 'string',
                                                format: 'binary',
                                                default: api.req_body_other
                                            }
                                        });
                                        break;
                                    }
                                    default:
                                        break;
                                }
                            }
                            return paramArray;
                        })();
                        apiItem['responses'] = {
                            '200': {
                                description: 'successful operation',
                                schema: (function () {
                                    var schemaObj = {};
                                    if (api.res_body_type === 'raw') {
                                        schemaObj['type'] = 'string';
                                        schemaObj['format'] = 'binary';
                                        schemaObj['default'] = api.res_body;
                                    }
                                    else if (api.res_body_type === 'json') {
                                        // 兼容内部版本
                                        var body = api.res_body_is_json_schema
                                            ? 'res_schema_body' in api
                                                ? api.res_schema_body
                                                : api.res_body
                                            : api.res_body;
                                        if (body) {
                                            var resBody = JSON5.parse(body);
                                            if (resBody !== null) {
                                                if (resBody['type']) {
                                                    schemaObj = resBody; // as the parameters,
                                                }
                                                else {
                                                    // required
                                                    if (required) {
                                                        resBody = JSON.parse(JSON.stringify(resBody).replace(/"([^*"]+":)/g, function (all, name) { return "\"*" + name; }));
                                                    }
                                                    schemaObj = easy_json_schema_1.default(resBody);
                                                }
                                                if (schemaObj.properties && schemaObj.properties.code) {
                                                    if (typeof schemaObj.properties.code === 'object') {
                                                        schemaObj.properties.code.type = 'number';
                                                    }
                                                }
                                                if (!schemaObj['title'] ||
                                                    schemaObj['title'].indexOf('empty object') !== -1) {
                                                    schemaObj['title'] = _.flow(_.camelCase, _.upperFirst)(url.replace(/\//g, '-'));
                                                }
                                            }
                                        }
                                    }
                                    return schemaObj;
                                })()
                            }
                        };
                        return apiItem;
                    })();
                };
                // list of category
                for (var _i = 0, _a = category.list; _i < _a.length; _i++) {
                    var api = _a[_i];
                    _loop_2(api);
                }
            };
            for (var _i = 0, list_1 = list; _i < list_1.length; _i++) {
                var category = list_1[_i];
                _loop_1(category);
            }
            return apisObj;
        })()
    };
    return swaggerObj;
}
exports.default = yapiJSon2swagger;
//# sourceMappingURL=yapiJSon2swagger.js.map