"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SecService = void 0;
const Fs = require('fs');
const urlJoin = require("url-join");
const botlib_1 = require("botlib");
const pragmatismo_io_framework_1 = require("pragmatismo-io-framework");
const models_1 = require("../models");
/**
 * Security service layer.
 */
class SecService extends botlib_1.GBService {
    async importSecurityFile(localPath, instance) {
        const security = JSON.parse(Fs.readFileSync(urlJoin(localPath, 'security.json'), 'utf8'));
        await pragmatismo_io_framework_1.CollectionUtil.asyncForEach(security.groups, async (group) => {
            const groupDb = models_1.GuaribasGroup.build({
                instanceId: instance.instanceId,
                displayName: group.displayName
            });
            const g1 = await groupDb.save();
            await pragmatismo_io_framework_1.CollectionUtil.asyncForEach(group.users, async (user) => {
                const userDb = models_1.GuaribasUser.build({
                    instanceId: instance.instanceId,
                    groupId: g1.groupId,
                    userName: user.userName
                });
                const user2 = await userDb.save();
                const userGroup = models_1.GuaribasUserGroup.build();
                userGroup.groupId = g1.groupId;
                userGroup.userId = user2.userId;
                await userGroup.save();
            });
        });
    }
    async ensureUser(instanceId, userSystemId, userName, address, channelName, displayName, email) {
        let user = await models_1.GuaribasUser.findOne({
            where: {
                userSystemId: userSystemId
            }
        });
        if (!user) {
            user = models_1.GuaribasUser.build();
        }
        user.instanceId = instanceId;
        user.userSystemId = userSystemId;
        user.userName = userName;
        user.displayName = displayName;
        user.email = email;
        user.defaultChannel = channelName;
        return await user.save();
    }
    /**
     * Retrives a conversation reference from contact phone.
     */
    async getConversationReference(phone) {
        const options = { where: { phone: phone } };
        const user = await models_1.GuaribasUser.findOne(options);
        return JSON.parse(user.conversationReference);
    }
    /**
     * Updates a conversation reference from contact phone.
     */
    async updateConversationReference(phone, conversationReference) {
        const options = { where: { phone: phone } };
        const user = await models_1.GuaribasUser.findOne(options);
        user.conversationReference = conversationReference;
        await user.save();
    }
    async updateConversationReferenceById(userId, conversationReference) {
        const options = { where: { userId: userId } };
        const user = await models_1.GuaribasUser.findOne(options);
        user.conversationReference = conversationReference;
        await user.save();
    }
    async updateUserLocale(userId, locale) {
        const user = await models_1.GuaribasUser.findOne({
            where: {
                userId: userId
            }
        });
        user.locale = locale;
        return await user.save();
    }
    async updateUserHearOnDialog(userId, dialogName) {
        const user = await models_1.GuaribasUser.findOne({
            where: {
                userId: userId
            }
        });
        user.hearOnDialog = dialogName;
        return await user.save();
    }
    async updateUserInstance(userSystemId, instanceId) {
        const user = await models_1.GuaribasUser.findOne({
            where: {
                userSystemId: userSystemId
            }
        });
        user.instanceId = instanceId;
        return await user.save();
    }
    /**
     * Finds and update user agent information to a next available person.
     */
    async updateHumanAgent(userSystemId, instanceId, agentSystemId) {
        const user = await models_1.GuaribasUser.findOne({
            where: {
                userSystemId: userSystemId,
                instanceId: instanceId
            }
        });
        if (agentSystemId === null) {
            const agent = await models_1.GuaribasUser.findOne({
                where: {
                    userSystemId: user.agentSystemId
                }
            });
            if (agent !== null && agent !== undefined) {
                agent.agentMode = 'bot';
                agent.agentSystemId = null;
                await agent.save();
            }
            user.agentMode = 'bot';
            user.agentSystemId = null;
        }
        else {
            user.agentMode = 'human';
            user.agentSystemId = agentSystemId;
            const agent = await models_1.GuaribasUser.findOne({
                where: {
                    userSystemId: agentSystemId
                }
            });
            agent.instanceId = user.instanceId;
            agent.agentMode = 'self';
            agent.agentSystemId = null;
            await agent.save();
        }
        await user.save();
        return user;
    }
    async isAgentSystemId(systemId) {
        const user = await models_1.GuaribasUser.findOne({
            where: {
                userSystemId: systemId
            }
        });
        if (user === null) {
            throw new Error(`TRANSFER_TO phones must talk first to the bot before becoming an agent.`);
        }
        return user.agentMode === 'self';
    }
    async assignHumanAgent(userSystemId, instanceId) {
        let agentSystemId;
        const list = process.env.TRANSFER_TO.split(';');
        await pragmatismo_io_framework_1.CollectionUtil.asyncForEach(list, async (item) => {
            if (!(await this.isAgentSystemId(item)) &&
                item !== undefined &&
                agentSystemId === undefined &&
                item !== userSystemId) {
                // TODO: Optimize loop.
                agentSystemId = item;
            }
        });
        await this.updateHumanAgent(userSystemId, instanceId, agentSystemId);
        return agentSystemId;
    }
    async getUserFromSystemId(systemId) {
        return await models_1.GuaribasUser.findOne({
            where: {
                userSystemId: systemId
            }
        });
    }
    async getUserFromAgentSystemId(systemId) {
        return await models_1.GuaribasUser.findOne({
            where: {
                agentSystemId: systemId
            }
        });
    }
    async getAllUsers(instanceId) {
        return await models_1.GuaribasUser.findAll({
            where: {
                instanceId: instanceId
            }
        });
    }
}
exports.SecService = SecService;
//# sourceMappingURL=SecService.js.map