"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ApiCore = void 0;
const axios_1 = __importDefault(require("axios"));
const hot_1 = require("../../../../shared/hot");
const const_1 = require("@mometa/fs-handler/const");
const lodash_es_1 = require("lodash-es");
const react_1 = __importDefault(require("react"));
const delay = (ms) => new Promise((res) => setTimeout(res, ms));
class ApiCore {
    constructor(apiBaseURL = '', toast) {
        this.apiBaseURL = apiBaseURL;
        this.toast = toast;
        this.axios = axios_1.default.create({
            baseURL: apiBaseURL,
            validateStatus: (status) => status < 400
        });
        this.axios.interceptors.response.use(undefined, (error) => {
            var _a, _b, _c, _d, _e, _f;
            console.error('axios error', Object.assign({}, error));
            if ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.error) {
                const err = new Error((_d = (_c = error.response) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d.error);
                err.toastElement = react_1.default.createElement("pre", { style: { textAlign: 'left', maxHeight: 400 } }, (_f = (_e = error.response) === null || _e === void 0 ? void 0 : _e.data) === null || _f === void 0 ? void 0 : _f.error);
                throw err;
            }
        });
    }
    openEditor(body) {
        return __awaiter(this, void 0, void 0, function* () {
            return this.doAsync(this.axios.post('/open-editor', body), {
                beforeMessage: `打开编辑器中...`
            });
        });
    }
    doAsync(prom, { beforeMessage = '' } = {}) {
        return __awaiter(this, void 0, void 0, function* () {
            const p = Promise.resolve(prom);
            const runP = p.finally(() => {
                dispose === null || dispose === void 0 ? void 0 : dispose();
            });
            let dispose;
            Promise.race([runP, delay(100).then(() => 'TIME_OUT')]).then((res) => {
                if (res === 'TIME_OUT') {
                    if (beforeMessage) {
                        dispose = this.toast.loading(beforeMessage);
                    }
                }
            }, (err) => {
                var _a;
                const msg = (_a = err.toastElement) !== null && _a !== void 0 ? _a : err.message;
                this.toast.error(msg);
                throw err;
            });
            return runP;
        });
    }
    submitOperation(requestData, label) {
        return __awaiter(this, void 0, void 0, function* () {
            requestData.preload = (0, lodash_es_1.pick)(requestData.preload, [
                'filename',
                'relativeFilename',
                'start',
                'end',
                'text',
                'data',
                'to'
            ]);
            const p = new Promise((resolve, reject) => {
                let updated;
                let received;
                let receivedData;
                let timer = setTimeout(() => {
                    resolve(true);
                }, 10000);
                const resolveMaybe = () => {
                    if (updated && received) {
                        clearTimeout(timer);
                        resolve(receivedData);
                    }
                };
                let dispose = (0, hot_1.addExecuteRuntimeListener)((exports, id) => {
                    function stripRequest(path) {
                        const paths = path.split(/(!+)/);
                        return paths[paths.length - 1];
                    }
                    console.log('addExecuteRuntimeListener id', id, ', striped: ', stripRequest(id));
                    // @ts-ignore
                    if (`./${requestData.preload.relativeFilename}` === stripRequest(id)) {
                        updated = true;
                        resolveMaybe();
                        dispose();
                    }
                });
                this._submitOperation(requestData).then((data) => {
                    received = true;
                    receivedData = data;
                    resolveMaybe();
                }, reject);
            });
            const stringType = label !== null && label !== void 0 ? label : {
                [const_1.OpType.DEL]: '删除',
                [const_1.OpType.REPLACE_NODE]: '替换节点',
                [const_1.OpType.MOVE_NODE]: '移动节点',
                [const_1.OpType.INSERT_NODE]: '插入节点'
            }[requestData.type];
            return this.doAsync(p, {
                beforeMessage: `执行 ${stringType !== null && stringType !== void 0 ? stringType : requestData.type} 操作中...`
            });
        });
    }
}
exports.ApiCore = ApiCore;
//# sourceMappingURL=api-core.js.map