"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RoomTracker = void 0;
const MatrixError_1 = require("../models/MatrixError");
// noinspection ES6RedundantAwait
/**
 * Tracks room encryption status for a MatrixClient.
 * @category Encryption
 */
class RoomTracker {
    client;
    constructor(client) {
        this.client = client;
    }
    /**
     * Handles a room join
     * @internal
     * @param roomId The room ID.
     */
    async onRoomJoin(roomId) {
        await this.queueRoomCheck(roomId);
    }
    /**
     * Handles a room event.
     * @internal
     * @param roomId The room ID.
     * @param event The event.
     */
    async onRoomEvent(roomId, event) {
        if (event['state_key'] !== '')
            return; // we don't care about anything else
        if (event['type'] === 'm.room.encryption' || event['type'] === 'm.room.history_visibility') {
            await this.queueRoomCheck(roomId);
        }
    }
    /**
     * Queues a room check for the tracker. If the room needs an update to the store, an
     * update will be made.
     * @param {string} roomId The room ID to check.
     */
    async queueRoomCheck(roomId) {
        const config = await this.client.cryptoStore.getRoom(roomId);
        if (config) {
            if (config.algorithm !== undefined) {
                return; // assume no change to encryption config
            }
        }
        let encEvent;
        try {
            encEvent = await this.client.getRoomStateEvent(roomId, "m.room.encryption", "");
            encEvent.algorithm = encEvent.algorithm ?? 'UNKNOWN';
        }
        catch (e) {
            if (e instanceof MatrixError_1.MatrixError && e.errcode === "M_NOT_FOUND") {
                encEvent = {};
            }
            else {
                return; // Other failures should not be cached.
            }
        }
        // Pick out the history visibility setting too
        let historyVisibility;
        try {
            const ev = await this.client.getRoomStateEvent(roomId, "m.room.history_visibility", "");
            historyVisibility = ev.history_visibility;
        }
        catch (e) {
            // ignore - we'll just treat history visibility as normal
        }
        await this.client.cryptoStore.storeRoom(roomId, {
            ...encEvent,
            historyVisibility,
        });
    }
    /**
     * Gets the room's crypto configuration, as known by the underlying store. If the room is
     * not encrypted then this will return an empty object.
     * @param {string} roomId The room ID to get the config for.
     * @returns {Promise<ICryptoRoomInformation>} Resolves to the encryption config.
     */
    async getRoomCryptoConfig(roomId) {
        let config = await this.client.cryptoStore.getRoom(roomId);
        if (!config) {
            await this.queueRoomCheck(roomId);
            config = await this.client.cryptoStore.getRoom(roomId);
        }
        if (!config) {
            return {};
        }
        return config;
    }
}
exports.RoomTracker = RoomTracker;
//# sourceMappingURL=RoomTracker.js.map