"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.authJwk = exports.handleRulesRestAPI = exports.verifyBodyData = exports.verifyMethod = void 0;
const http_status_codes_1 = __importDefault(require("http-status-codes"));
const rest_1 = require("../controllers/rest");
const debug_1 = require("../utils/debug");
const rules_1 = require("../controllers/rules");
function verifyMethod(request, response, next) {
    if (request.method === 'POST') {
        next();
    }
    else {
        response.status(http_status_codes_1.default.FORBIDDEN).json({ message: 'HTTP method not supported' });
    }
}
exports.verifyMethod = verifyMethod;
function verifyBodyData(request, response, next) {
    const body = request.body;
    if (!body) {
        response.status(http_status_codes_1.default.BAD_REQUEST).json({ message: 'require non empty rule blocks request' });
    }
    else if (Object.keys(body).length === 0) {
        response.status(http_status_codes_1.default.BAD_REQUEST).json({ message: 'require non empty rule blocks request' });
    }
    else {
        delete body.context;
        next();
    }
}
exports.verifyBodyData = verifyBodyData;
function handleRuleBlocks(request, response, _, authAdapter, filesAdapter, databaseAdapter, options) {
    const body = request.body;
    try {
        (0, debug_1.devLog)(JSON.stringify(body));
    }
    catch (e) {
    }
    const results = { errors: {} };
    (0, rules_1.handleAuthenticationRule)(body, results, authAdapter, databaseAdapter, options).then(_1 => {
        return (0, rules_1.handlePolicyRule)(body, results, databaseAdapter, options);
    }).then(_2 => {
        return (0, rules_1.handleCreateRules)(body, results, databaseAdapter, options, null);
    }).then(_3 => {
        return (0, rules_1.handleUpdateRules)(body, results, databaseAdapter, options, null);
    }).then(_4 => {
        return (0, rules_1.handleDeleteRules)(body, results, databaseAdapter, options, null);
    }).then(_5 => {
        return (0, rules_1.handleQueryRules)(body, results, databaseAdapter, options, null);
    }).then(_6 => {
        return (0, rules_1.handleBulkRules)(body, results, databaseAdapter, options);
    }).then(_8 => {
        return (0, rules_1.handleStorageRules)(body, results, databaseAdapter, authAdapter, filesAdapter, options);
    }).then(_9 => {
        return (0, rules_1.handleAggregationRules)(body, results, databaseAdapter, options);
    }).then(_10 => {
        if (!(results.errors && Object.keys(results.errors).length > 0))
            delete results.errors;
        response.status(http_status_codes_1.default.OK).json(results);
    }).catch(reason => {
        response.status(http_status_codes_1.default.EXPECTATION_FAILED).json({ message: reason.message ? reason.message : reason.toString() });
    });
}
function handleRulesRestAPI(prefix = '/', authAdapter, filesAdapter, databaseAdapter, optionsFn) {
    return {
        path: `${prefix}v2`,
        method: 'POST',
        onRequest: [
            (rq, rs, n) => verifyMethod(rq, rs, n),
            (rq, rs, n) => verifyBodyData(rq, rs, n),
            (rq, rs, n) => (0, rest_1.verifyApplicationId)(rq, rs, n, optionsFn(rq)),
            (rq, rs, n) => (0, rest_1.verifyRequestToken)(rq, rs, n, optionsFn(rq)),
            (rq, rs, n) => handleRuleBlocks(rq, rs, n, authAdapter, filesAdapter, databaseAdapter, optionsFn(rq))
        ]
    };
}
exports.handleRulesRestAPI = handleRulesRestAPI;
function authJwk(options) {
    return {
        path: '/jwk',
        method: 'GET',
        onRequest: (request, response) => {
            if (options.rsaPublicKeyInJson) {
                response.status(200).json(options.rsaPublicKeyInJson);
            }
            else {
                response.status(http_status_codes_1.default.EXPECTATION_FAILED).json({ message: 'fail to retrieve public key' });
            }
        }
    };
}
exports.authJwk = authJwk;
