"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.errorHandlerPlugin = exports.ERROR_STATUS = void 0;
exports.mapStatus = mapStatus;
const fastify_plugin_1 = __importDefault(require("fastify-plugin"));
const errors_1 = require("@yinuo-ngm/errors");
exports.ERROR_STATUS = {
    [errors_1.GlobalErrorCodes.UNKNOWN_ERROR]: 500,
    [errors_1.GlobalErrorCodes.BAD_REQUEST]: 400,
    [errors_1.GlobalErrorCodes.NOT_FOUND]: 404,
    [errors_1.GlobalErrorCodes.NOT_IMPLEMENTED]: 501,
    [errors_1.GlobalErrorCodes.STORAGE_IO_ERROR]: 500,
    [errors_1.GlobalErrorCodes.FS_PATH_NOT_FOUND]: 404,
    [errors_1.GlobalErrorCodes.FS_PERMISSION_DENIED]: 403,
    [errors_1.GlobalErrorCodes.FS_ALREADY_EXISTS]: 409,
    [errors_1.GlobalErrorCodes.FS_INVALID_NAME]: 400,
    [errors_1.GlobalErrorCodes.FS_MKDIR_FAILED]: 500,
    [errors_1.GlobalErrorCodes.BAD_JSON]: 400,
    [errors_1.GlobalErrorCodes.BAD_MSG]: 400,
    [errors_1.GlobalErrorCodes.OP_NOT_SUPPORTED]: 400,
    [errors_1.GlobalErrorCodes.TOPIC_NOT_FOUND]: 404,
    [errors_1.GlobalErrorCodes.HANDLER_FAILED]: 500,
    [errors_1.GlobalErrorCodes.OP_NOT_FOUND]: 400,
    [errors_1.GlobalErrorCodes.UNAUTHORIZED]: 401,
    [errors_1.GlobalErrorCodes.INVALID_TIMESTAMP]: 400,
    [errors_1.CoreErrorCodes.PROJECT_NOT_FOUND]: 404,
    [errors_1.CoreErrorCodes.PROJECT_ROOT_INVALID]: 400,
    [errors_1.CoreErrorCodes.PROJECT_ALREADY_EXISTS]: 409,
    [errors_1.CoreErrorCodes.PROJECT_ID_REQUIRED]: 400,
    [errors_1.CoreErrorCodes.PROJECT_IMPORT_NOT_EXISTS]: 404,
    [errors_1.CoreErrorCodes.PROJECT_IMPORT_NOT_DIR]: 400,
    [errors_1.CoreErrorCodes.PROJECT_IMPORT_ALREADY_REGISTERED]: 409,
    [errors_1.CoreErrorCodes.PROJECT_IMPORT_NOT_RECOGNIZED]: 422,
    [errors_1.CoreErrorCodes.PROJECT_IMPORT_SCAN_FAILED]: 500,
    [errors_1.CoreErrorCodes.BOOTSTRAP_NOT_IN_PICK_STATE]: 400,
    [errors_1.CoreErrorCodes.BOOTSTRAP_CTX_NOT_FOUND]: 404,
    [errors_1.CoreErrorCodes.BOOTSTRAP_INVALID_PICKED_ROOT]: 400,
    [errors_1.CoreErrorCodes.BOOTSTRAP_NOT_WAITING_PICK]: 400,
    [errors_1.CoreErrorCodes.INVALID_NAME]: 400,
    [errors_1.CoreErrorCodes.TARGET_EXISTS]: 409,
    [errors_1.CoreErrorCodes.INVALID_REPO_URL]: 400,
    [errors_1.CoreErrorCodes.INVALID_PARENT_DIR]: 400,
    [errors_1.CoreErrorCodes.GIT_CHECKOUT_FAILED]: 500,
    [errors_1.CoreErrorCodes.PROJECT_ANGULAR_JSON_INVALID]: 400,
    [errors_1.CoreErrorCodes.PROJECT_ANGULAR_JSON_NOT_FOUND]: 404,
    [errors_1.CoreErrorCodes.PROJECT_VITE_CONFIG_INVALID]: 400,
    [errors_1.CoreErrorCodes.PROJECT_VUE_CONFIG_NOT_FOUND]: 404,
    [errors_1.CoreErrorCodes.ASSET_NOT_FOUND]: 404,
    [errors_1.CoreErrorCodes.ASSET_KIND_NOT_SUPPORTED]: 400,
    [errors_1.CoreErrorCodes.ASSET_URL_REQUIRED]: 400,
    [errors_1.CoreErrorCodes.ASSET_LABEL_REQUIRED]: 400,
    [errors_1.CoreErrorCodes.ASSET_URL_INVALID]: 400,
    [errors_1.CoreErrorCodes.ASSET_MODE_INVALID]: 400,
    [errors_1.CoreErrorCodes.CONFIG_BACKUP_NOT_FOUND]: 404,
    [errors_1.CoreErrorCodes.CONFIG_READ_FAILED]: 500,
    [errors_1.CoreErrorCodes.CONFIG_WRITE_FAILED]: 500,
    [errors_1.CoreErrorCodes.CONFIG_CONFLICT]: 409,
    [errors_1.CoreErrorCodes.CONFIG_OPEN_FAILED]: 500,
    [errors_1.CoreErrorCodes.CONFIG_SCHEMA_NOT_FOUND]: 404,
    [errors_1.CoreErrorCodes.CONFIG_DOMAIN_NOT_FOUND]: 404,
    [errors_1.CoreErrorCodes.CONFIG_DOC_NOT_FOUND]: 404,
    [errors_1.CoreErrorCodes.TASK_NOT_FOUND]: 404,
    [errors_1.CoreErrorCodes.RUN_NOT_FOUND]: 404,
    [errors_1.CoreErrorCodes.TASK_ID_REQUIRED]: 400,
    [errors_1.CoreErrorCodes.TASK_ALREADY_RUNNING]: 409,
    [errors_1.CoreErrorCodes.PROCESS_SPAWN_FAILED]: 500,
    [errors_1.CoreErrorCodes.TASK_SPEC_NOT_FOUND]: 404,
    [errors_1.CoreErrorCodes.TASK_NOT_RUNNABLE]: 400,
    [errors_1.CoreErrorCodes.COMMAND_NOT_FOUND]: 404,
    [errors_1.CoreErrorCodes.FS_EXISTS_FAILED]: 500,
    [errors_1.CoreErrorCodes.FS_INVALID_NAME]: 400,
    [errors_1.CoreErrorCodes.FS_ALREADY_EXISTS]: 409,
    [errors_1.CoreErrorCodes.FS_PERMISSION_DENIED]: 403,
    [errors_1.CoreErrorCodes.FS_MKDIR_FAILED]: 500,
    [errors_1.CoreErrorCodes.FS_PATH_NOT_FOUND]: 404,
    [errors_1.CoreErrorCodes.DASHBOARD_CONFLICT]: 409,
    [errors_1.CoreErrorCodes.WIDGET_NOT_FOUND]: 404,
    [errors_1.CoreErrorCodes.WIDGET_LOCKED]: 423,
    [errors_1.CoreErrorCodes.SPRITE_CONFIG_NOT_FOUND]: 404,
    [errors_1.CoreErrorCodes.SPRITE_GROUP_NOT_FOUND]: 404,
    [errors_1.CoreErrorCodes.SPRITE_ICONS_ROOT_NOT_FOUND]: 404,
    [errors_1.CoreErrorCodes.SVN_SYNC_ALREADY_RUNNING]: 409,
    [errors_1.CoreErrorCodes.SVN_SYNC_FAILED]: 500,
    [errors_1.CoreErrorCodes.SVN_SOURCE_ID_REQUIRED]: 400,
    [errors_1.CoreErrorCodes.DEP_INSTALL_FAILED]: 500,
    [errors_1.CoreErrorCodes.DEP_UNINSTALL_FAILED]: 500,
    [errors_1.CoreErrorCodes.DEP_NOT_FOUND]: 404,
    [errors_1.CoreErrorCodes.NO_VERSION_MANAGER]: 503,
    [errors_1.CoreErrorCodes.SWITCH_VERSION_FAILED]: 500,
    [errors_1.CoreErrorCodes.NO_AVAILABLE_VERSIONS]: 409,
    [errors_1.CoreErrorCodes.VERSION_REQUIRED]: 400,
    [errors_1.CoreErrorCodes.PROJECT_PATH_REQUIRED]: 400,
    [errors_1.CoreErrorCodes.EDITOR_NOT_FOUND]: 404,
    [errors_1.CoreErrorCodes.EDITOR_LAUNCH_FAILED]: 500,
    [errors_1.CoreErrorCodes.RSS_FETCH_FAILED]: 500,
    [errors_1.CoreErrorCodes.INVALID_RSS_URL]: 400,
    [errors_1.CoreErrorCodes.KILL_PORT_FAILED]: 500,
    [errors_1.CoreErrorCodes.INVALID_PORT]: 400,
};
function mapStatus(code) {
    return exports.ERROR_STATUS[code] ?? 400;
}
function buildErrorBody(reqId, code, message, details) {
    return {
        ok: false,
        error: {
            code,
            message,
            ...(details !== undefined ? { details } : {}),
        },
        meta: {
            requestId: reqId,
            ts: Date.now(),
        },
    };
}
exports.errorHandlerPlugin = (0, fastify_plugin_1.default)(async (app) => {
    app.setErrorHandler((err, req, reply) => {
        const requestId = req.id;
        if (err instanceof errors_1.AppError || isAppErrorLike(err)) {
            const status = mapStatus(err.code);
            return reply.status(status).send(buildErrorBody(requestId, err.code, err.message, err.meta));
        }
        if (err?.validation) {
            return reply
                .status(400)
                .send(buildErrorBody(requestId, errors_1.GlobalErrorCodes.BAD_REQUEST, "参数不合法", err.validation));
        }
        req.log.error({ err, requestId }, "Unhandled error");
        return reply.status(500).send(buildErrorBody(requestId, errors_1.GlobalErrorCodes.UNKNOWN_ERROR, "服务异常，请稍后重试"));
    });
});
function isAppErrorLike(err) {
    return err !== null && typeof err === 'object' && typeof err.code === 'number' && typeof err.message === 'string';
}
exports.default = exports.errorHandlerPlugin;
