'use strict';
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.addRole = addRole;
exports.alterRole = alterRole;
exports.dropRole = dropRole;
exports.getRoleByName = getRoleByName;
exports.listRoles = listRoles;
const insert = __importStar(require("../dataLayer/insert.js"));
const search = __importStar(require("../dataLayer/search.js"));
const delete_ = __importStar(require("../dataLayer/delete.js"));
const validation = __importStar(require("../validation/role_validation.js"));
const signalling = __importStar(require("../utility/signalling.js"));
const util = __importStar(require("util"));
const terms = __importStar(require("../utility/hdbTerms.js"));
const hdbUtils = __importStar(require("../utility/common_utils.js"));
const databases_ts_1 = require("../resources/databases.js");
const pSearchSearchByValue = search.searchByValue;
const pSearchSearchByHash = search.searchByHash;
const pDeleteDelete = util.promisify(delete_.delete_);
const SearchObject_ts_1 = __importDefault(require("../dataLayer/SearchObject.js"));
const SearchByHashObject_ts_1 = __importDefault(require("../dataLayer/SearchByHashObject.js"));
const hdbError_ts_1 = require("../utility/errors/hdbError.js");
const commonErrors_ts_1 = require("../utility/errors/commonErrors.js");
const itc_js_1 = require("../server/threads/itc.js");
function scrubRoleDetails(role) {
    try {
        if (role.hdb_auth_header) {
            delete role.hdb_auth_header;
        }
        if (role.HDB_INTERNAL_PATH) {
            delete role.HDB_INTERNAL_PATH;
        }
        if (role.operation) {
            delete role.operation;
        }
        if (role.hdb_user) {
            delete role.hdb_user;
        }
    }
    catch {
        //no-op, failure is ok
    }
    return role;
}
async function addRole(role) {
    let validationResp = validation.addRoleValidation(role);
    if (validationResp) {
        throw validationResp;
    }
    role = scrubRoleDetails(role);
    let searchObj = {
        schema: 'system',
        table: 'hdb_role',
        attribute: 'role',
        value: role.role,
        hash_attribute: 'id',
        get_attributes: ['*'],
    };
    let searchRole;
    try {
        // here, and for other interactions, need convert to real array
        searchRole = Array.from((await pSearchSearchByValue(searchObj)) || []);
    }
    catch (err) {
        throw (0, hdbError_ts_1.handleHDBError)(err, undefined, undefined, undefined, undefined, undefined);
    }
    if (searchRole && searchRole.length > 0) {
        throw (0, hdbError_ts_1.handleHDBError)(new Error(), commonErrors_ts_1.HDB_ERROR_MSGS.ROLE_ALREADY_EXISTS(role.role), commonErrors_ts_1.HTTP_STATUS_CODES.CONFLICT, undefined, undefined, true);
    }
    if (!role.id)
        role.id = role.role;
    let insertObject = {
        operation: 'insert',
        schema: 'system',
        table: 'hdb_role',
        hash_attribute: 'id',
        records: [role],
    };
    await insert.insert(insertObject);
    signalling.signalUserChange(new itc_js_1.UserEventMsg(process.pid));
    role = scrubRoleDetails(role);
    return role;
}
async function alterRole(role) {
    let validationResp = validation.alterRoleValidation(role);
    if (validationResp) {
        throw validationResp;
    }
    role = scrubRoleDetails(role);
    let updateObject = {
        operation: 'update',
        schema: 'system',
        table: 'hdb_role',
        records: [role],
    };
    let updateResponse;
    try {
        updateResponse = await insert.update(updateObject);
    }
    catch (err) {
        throw (0, hdbError_ts_1.handleHDBError)(err, undefined, undefined, undefined, undefined, undefined);
    }
    if (updateResponse && updateResponse?.message === 'updated 0 of 1 records') {
        throw (0, hdbError_ts_1.handleHDBError)(new Error(), 'Invalid role id', commonErrors_ts_1.HTTP_STATUS_CODES.BAD_REQUEST, undefined, undefined, true);
    }
    await signalling.signalUserChange(new itc_js_1.UserEventMsg(process.pid));
    return role;
}
async function dropRole(role) {
    let validationResp = validation.dropRoleValidation(role);
    if (validationResp) {
        throw (0, hdbError_ts_1.handleHDBError)(new Error(), validationResp, commonErrors_ts_1.HTTP_STATUS_CODES.BAD_REQUEST, undefined, undefined, true);
    }
    let roleIdSearch = new SearchByHashObject_ts_1.default(terms.SYSTEM_SCHEMA_NAME, terms.SYSTEM_TABLE_NAMES.ROLE_TABLE_NAME, [role.id], ['role']);
    let roleName = Array.from(await pSearchSearchByHash(roleIdSearch));
    if (roleName.length === 0) {
        throw (0, hdbError_ts_1.handleHDBError)(new Error(), commonErrors_ts_1.HDB_ERROR_MSGS.ROLE_NOT_FOUND, commonErrors_ts_1.HTTP_STATUS_CODES.NOT_FOUND, undefined, undefined, true);
    }
    let searchUserByRoleid = new SearchObject_ts_1.default(terms.SYSTEM_SCHEMA_NAME, terms.SYSTEM_TABLE_NAMES.USER_TABLE_NAME, 'role', role.id, undefined, ['username', 'active']);
    let foundUsers = Array.from(await pSearchSearchByValue(searchUserByRoleid));
    let activeUsers = false;
    if (hdbUtils.isEmptyOrZeroLength(foundUsers) === false) {
        for (let k = 0; k < foundUsers.length; k++) {
            if (foundUsers[k].active === true) {
                activeUsers = true;
                break;
            }
        }
    }
    if (activeUsers === true) {
        throw (0, hdbError_ts_1.handleHDBError)(new Error(), `Cannot drop role ${roleName[0].role} as it has active user(s) tied to this role`, commonErrors_ts_1.HTTP_STATUS_CODES.CONFLICT, undefined, undefined, true);
    }
    let deleteObject = {
        table: 'hdb_role',
        schema: 'system',
        hash_values: [role.id],
    };
    await pDeleteDelete(deleteObject);
    signalling.signalUserChange(new itc_js_1.UserEventMsg(process.pid));
    return `${roleName[0].role} successfully deleted`;
}
async function getRoleByName(roleName) {
    for await (const role of databases_ts_1.databases.system.hdb_role.search([{ attribute: 'role', value: roleName }])) {
        return role;
    }
    return null;
}
async function listRoles() {
    let searchObj = {
        table: 'hdb_role',
        schema: 'system',
        hash_attribute: 'id',
        attribute: 'id',
        value: '*',
        get_attributes: ['*'],
    };
    return pSearchSearchByValue(searchObj);
}
//# sourceMappingURL=role.js.map