"use strict";
// SPDX-FileCopyrightText: 2022 - 2024 Gnuxie <Gnuxie@protonmail.com>
// SPDX-FileCopyrightText: 2022 The Matrix.org Foundation C.I.C.
//
// SPDX-License-Identifier: Apache-2.0
//
// SPDX-FileAttributionText: <text>
// This modified file incorporates work from mjolnir
// https://github.com/matrix-org/mjolnir
// </text>
Object.defineProperty(exports, "__esModule", { value: true });
exports.PolicyChangeNotification = void 0;
const matrix_protection_suite_1 = require("matrix-protection-suite");
const mps_interface_adaptor_1 = require("@the-draupnir-project/mps-interface-adaptor");
const matrix_basic_types_1 = require("@the-draupnir-project/matrix-basic-types");
const interface_manager_1 = require("@the-draupnir-project/interface-manager");
const Rules_1 = require("../commands/Rules");
const NotificationRoom_1 = require("./NotificationRoom/NotificationRoom");
const typebox_1 = require("@sinclair/typebox");
const log = new matrix_protection_suite_1.Logger("PolicyChangeNotification");
const PolicyChangeNotificationSettings = typebox_1.Type.Object({
    notificationRoomID: typebox_1.Type.Optional(typebox_1.Type.Union([matrix_protection_suite_1.StringRoomIDSchema, typebox_1.Type.Undefined()], {
        default: undefined,
        description: "The room where notifications should be sent.",
    })),
});
class PolicyChangeNotification extends matrix_protection_suite_1.AbstractProtection {
    draupnir;
    notificationRoomID;
    constructor(description, lifetime, capabilities, protectedRoomsSet, draupnir, notificationRoomID) {
        super(description, lifetime, capabilities, protectedRoomsSet, {});
        this.draupnir = draupnir;
        this.notificationRoomID = notificationRoomID;
    }
    async handlePolicyChange(revision, changes) {
        if (changes.length === 0) {
            return (0, matrix_protection_suite_1.Ok)(undefined);
        }
        const changesByList = new Map();
        for (const change of changes) {
            const entry = changesByList.get(change.event.room_id);
            if (entry === undefined) {
                changesByList.set(change.event.room_id, [change]);
            }
            else {
                entry.push(change);
            }
        }
        const groupedChanges = await groupRulesByIssuer(this.draupnir.policyRoomManager, changesByList);
        if ((0, matrix_protection_suite_1.isError)(groupedChanges)) {
            return groupedChanges;
        }
        const sendResult = await (0, mps_interface_adaptor_1.sendMatrixEventsFromDeadDocument)(this.draupnir.clientPlatform.toRoomMessageSender(), this.notificationRoomID, interface_manager_1.DeadDocumentJSX.JSXFactory("root", null, renderGroupedChanges(groupedChanges.ok)), {});
        if ((0, matrix_protection_suite_1.isError)(sendResult)) {
            log.error(`couldn't send change to management room`, sendResult.error);
        }
        return (0, matrix_protection_suite_1.Ok)(undefined);
    }
}
exports.PolicyChangeNotification = PolicyChangeNotification;
async function groupRulesByIssuer(policyRoomManager, changesByList) {
    const groupedChanges = [];
    for (const [roomID, changes] of changesByList) {
        const issuer = await policyRoomManager.getPolicyRoomRevisionIssuer(matrix_basic_types_1.MatrixRoomReference.fromRoomID(roomID));
        if ((0, matrix_protection_suite_1.isError)(issuer)) {
            return issuer;
        }
        else {
            groupedChanges.push({
                issuer: issuer.ok,
                changes: changes,
            });
        }
    }
    return (0, matrix_protection_suite_1.Ok)(groupedChanges);
}
function renderListChange(change) {
    return (interface_manager_1.DeadDocumentJSX.JSXFactory("fragment", null,
        interface_manager_1.DeadDocumentJSX.JSXFactory("li", null,
            (0, mps_interface_adaptor_1.renderMentionPill)(change.sender, change.sender),
            " ",
            interface_manager_1.DeadDocumentJSX.JSXFactory("code", null, change.changeType),
            "  ",
            change.rule.kind,
            " (",
            interface_manager_1.DeadDocumentJSX.JSXFactory("code", null, change.rule.recommendation),
            ")  ",
            change.rule.matchType === matrix_protection_suite_1.PolicyRuleMatchType.HashedLiteral
                ? (0, Rules_1.renderRuleHashes)(change.rule)
                : (0, Rules_1.renderRuleClearText)(change.rule))));
}
function renderListChanges({ issuer, changes }) {
    return (interface_manager_1.DeadDocumentJSX.JSXFactory("fragment", null,
        (0, mps_interface_adaptor_1.renderRoomPill)(issuer.room),
        " (shortcode:",
        " ",
        issuer.currentRevision.shortcode ?? "no shortcode",
        ")   updated with",
        " ",
        changes.length,
        " ",
        changes.length === 1 ? "change" : "changes",
        ":",
        interface_manager_1.DeadDocumentJSX.JSXFactory("ul", null, changes.map(renderListChange))));
}
function renderGroupedChanges(groupedChanges) {
    return interface_manager_1.DeadDocumentJSX.JSXFactory("fragment", null, groupedChanges.map(renderListChanges));
}
(0, matrix_protection_suite_1.describeProtection)({
    name: PolicyChangeNotification.name,
    description: "Provides notification of policy changes from watched lists.",
    capabilityInterfaces: {},
    defaultCapabilities: {},
    configSchema: PolicyChangeNotificationSettings,
    async factory(description, lifetime, protectedRoomsSet, draupnir, capabilities, settings) {
        if (settings.notificationRoomID === undefined) {
            return (await NotificationRoom_1.NotificationRoomCreator.createNotificationRoomFromDraupnir(draupnir, description, settings, "notificationRoomID", "Policy Change Notifications", log));
        }
        return (0, matrix_protection_suite_1.Ok)(new PolicyChangeNotification(description, lifetime, capabilities, protectedRoomsSet, draupnir, settings.notificationRoomID));
    },
});
//# sourceMappingURL=PolicyChangeNotification.js.map