"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
/* eslint-disable @typescript-eslint/no-var-requires */
var path = tslib_1.__importStar(require("path"));
var fs = tslib_1.__importStar(require("fs"));
var request = tslib_1.__importStar(require("request"));
var chalk_1 = tslib_1.__importDefault(require("chalk"));
var consts_1 = require("./consts");
var swagger2ts_1 = tslib_1.__importDefault(require("./swagger2ts"));
var serve_1 = tslib_1.__importDefault(require("./yapi/serve"));
var init_1 = require("./init");
var guard_1 = require("./guard");
var serve_2 = require("./diff/serve");
var defaultParseConfig = {
    '-l': 'typescript-angularjs',
    '-t': path.join(init_1.pluginsPath, 'typescript-tkit'),
    '-o': path.join(process.cwd(), 'src', 'services')
};
/** CLI入口函数 */
function gen(config, options) {
    return tslib_1.__awaiter(this, void 0, void 0, function () {
        var url, remoteUrl, _a, type, swaggerParser, _b, requestConfig, localSwaggerUrl, remoteSwaggerUrl, yapiTMP, updateLocalSwagger, swagger2tsConfig, servicesPath, code, swaggerData, guardConfig, warnings, _c, w_1, errors_1, _d, errors, w, suggestions, swaggerFileName, swaggerPath, res;
        var _this = this;
        return tslib_1.__generator(this, function (_e) {
            switch (_e.label) {
                case 0:
                    url = config.url, remoteUrl = config.remoteUrl, _a = config.type, type = _a === void 0 ? 'swagger' : _a, swaggerParser = config.swaggerParser, _b = config.requestConfig, requestConfig = _b === void 0 ? {} : _b;
                    if (!url || url.match(consts_1.RemoteUrlReg)) {
                        console.log(chalk_1.default.red("[ERROR]: \u81EA @3.1.* url \u5FC5\u987B\u662F\u672C\u5730\u5730\u5740"));
                        throw 1;
                    }
                    localSwaggerUrl = path.join(consts_1.ProjectDir, url);
                    remoteSwaggerUrl = (requestConfig.url = requestConfig.url || remoteUrl || '');
                    if (remoteSwaggerUrl) {
                        if (!remoteSwaggerUrl.match(consts_1.RemoteUrlReg)) {
                            remoteSwaggerUrl = path.join(consts_1.ProjectDir, remoteSwaggerUrl);
                            if (!fs.existsSync(remoteSwaggerUrl)) {
                                console.log(chalk_1.default.red("[ERROR]: remoteUrl \u6307\u5B9A\u7684\u6587\u4EF6 " + remoteUrl + " \u4E0D\u5B58\u5728"));
                                throw 1;
                            }
                        }
                    }
                    if (!(type === 'yapi')) return [3 /*break*/, 2];
                    return [4 /*yield*/, serve_1.default(remoteSwaggerUrl, config.yapiConfig)];
                case 1:
                    yapiTMP = _e.sent();
                    if ('result' in yapiTMP && yapiTMP.result && !yapiTMP.code) {
                        remoteSwaggerUrl = yapiTMP.result;
                    }
                    else {
                        console.log(chalk_1.default.red("[ERROR]: \u57FA\u4E8E YAPI \u751F\u6210\u5931\u8D25: " + yapiTMP.message));
                        throw 1;
                    }
                    _e.label = 2;
                case 2:
                    updateLocalSwagger = function (data) {
                        fs.writeFileSync(localSwaggerUrl, data ? JSON.stringify(data, null, 2) : data, {
                            encoding: 'utf8'
                        });
                    };
                    swagger2tsConfig = tslib_1.__assign(tslib_1.__assign({}, defaultParseConfig), swaggerParser);
                    servicesPath = swagger2tsConfig['-o'] || '';
                    return [4 /*yield*/, new Promise(function (rs) {
                            var loader = function (cb) {
                                remoteSwaggerUrl
                                    ? remoteSwaggerUrl.match(consts_1.RemoteUrlReg)
                                        ? request.get(tslib_1.__assign(tslib_1.__assign({}, requestConfig), { url: remoteSwaggerUrl }), function (err, res) { return cb(err, { body: JSON.parse(res.body) }); })
                                        : cb(undefined, { body: require(remoteSwaggerUrl) })
                                    : cb(undefined, {});
                            };
                            loader(function (err, _a) {
                                var newSwagger = _a.body;
                                return tslib_1.__awaiter(_this, void 0, void 0, function () {
                                    var localSwagger, merged;
                                    return tslib_1.__generator(this, function (_b) {
                                        switch (_b.label) {
                                            case 0:
                                                if (!err) return [3 /*break*/, 1];
                                                console.log(chalk_1.default.red("[ERROR]: \u4E0B\u8F7D Swagger JSON \u5931\u8D25: " + err));
                                                rs(1);
                                                return [3 /*break*/, 5];
                                            case 1:
                                                if (!fs.existsSync(servicesPath)) {
                                                    fs.mkdirSync(servicesPath);
                                                }
                                                if (!newSwagger) return [3 /*break*/, 4];
                                                if (!fs.existsSync(localSwaggerUrl)) return [3 /*break*/, 3];
                                                localSwagger = require(localSwaggerUrl);
                                                return [4 /*yield*/, serve_2.serveDiff(localSwagger, newSwagger)];
                                            case 2:
                                                merged = _b.sent();
                                                merged && updateLocalSwagger(merged);
                                                return [3 /*break*/, 4];
                                            case 3:
                                                updateLocalSwagger(newSwagger);
                                                _b.label = 4;
                                            case 4:
                                                rs(0);
                                                _b.label = 5;
                                            case 5: return [2 /*return*/];
                                        }
                                    });
                                });
                            });
                        })];
                case 3:
                    code = _e.sent();
                    if (code) {
                        return [2 /*return*/, code];
                    }
                    // @IMP: 删除缓存
                    delete require.cache[require.resolve(localSwaggerUrl)];
                    swaggerData = require(localSwaggerUrl);
                    guardConfig = config.guardConfig || {};
                    warnings = Array();
                    return [4 /*yield*/, guard_1.strictModeGuard(swaggerData, guardConfig)];
                case 4:
                    _c = _e.sent(), w_1 = _c.warnings, errors_1 = _c.errors;
                    warnings.push.apply(warnings, w_1);
                    if (errors_1.length) {
                        console.log(chalk_1.default.red(errors_1.join('\n')));
                        return [2 /*return*/, 1];
                    }
                    return [4 /*yield*/, (guardConfig.mode === 'strict'
                            ? { errors: [], warnings: [], suggestions: [] }
                            : guard_1.operationIdGuard(swaggerData, guardConfig))];
                case 5:
                    _d = _e.sent(), errors = _d.errors, w = _d.warnings, suggestions = _d.suggestions;
                    warnings.push.apply(warnings, w);
                    if (warnings.length) {
                        console.log(chalk_1.default.yellow(warnings.join('\n')));
                    }
                    swaggerFileName = init_1.basePathToFileName((swaggerData.basePath || init_1.DefaultBasePath) + ".json");
                    swaggerPath = path.join(init_1.SmTmpDir, swaggerFileName);
                    fs.writeFileSync(swaggerPath, JSON.stringify(swaggerData), {
                        encoding: 'utf8'
                    });
                    if (errors.length) {
                        console.log(chalk_1.default.red(errors.join('\n')));
                        if (suggestions.length) {
                            console.log(chalk_1.default.green(JSON.stringify(suggestions, undefined, 2)));
                        }
                        return [2 /*return*/, 1];
                    }
                    else {
                        if (suggestions.length) {
                            console.log(chalk_1.default.green(JSON.stringify(suggestions, undefined, 2)));
                        }
                    }
                    return [4 /*yield*/, swagger2ts_1.default(tslib_1.__assign(tslib_1.__assign({}, swagger2tsConfig), { '-i': swaggerPath }), options.clear)];
                case 6:
                    res = _e.sent();
                    if (res.code) {
                        console.log(chalk_1.default.red("[ERROR]: gen failed with: " + res.message));
                        return [2 /*return*/, 1];
                    }
                    else {
                        console.log(chalk_1.default.green("[INFO]: gen success with: " + localSwaggerUrl));
                        console.log(chalk_1.default.yellowBright("[IMP] \u8BF7\u5C06\u6587\u4EF6 " + localSwaggerUrl + " \u6DFB\u52A0\u5230\u7248\u672C\u4ED3\u5E93"));
                    }
                    return [2 /*return*/, 0];
            }
        });
    });
}
exports.default = gen;
//# sourceMappingURL=index.js.map