"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ActivationEventServiceImpl = void 0;
const tslib_1 = require("tslib");
const picomatch_1 = tslib_1.__importDefault(require("picomatch"));
const di_1 = require("@opensumi/di");
const ide_core_common_1 = require("@opensumi/ide-core-common");
/**
 * 管理和发出插件 activateEvents
 * event 格式
 * topic:data
 */
// topic可能支持data通配符，比如workspaceContains: **/a.json
let ActivationEventServiceImpl = class ActivationEventServiceImpl {
    constructor() {
        this.eventListeners = new Map();
        this.collectTopicData = new ide_core_common_1.MultiMap();
        this.wildCardTopics = new Set();
        this.activatedEventSet = new Set();
        this.wildCardTopics.add('workspaceContains');
    }
    getTopicsData(topic) {
        return this.collectTopicData.get(topic) || [];
    }
    async fireEvent(topic, data = '') {
        this.activatedEventSet.add(JSON.stringify({ topic, data }));
        let listeners;
        if (this.wildCardTopics.has(topic)) {
            listeners = this.eventListeners.get(topic);
        }
        else if (this.eventListeners.has(topic)) {
            listeners = this.eventListeners.get(topic);
        }
        else {
            listeners = this.eventListeners.get(topic + ':' + data);
        }
        if (listeners) {
            const result = await Promise.allSettled(listeners.map((listener) => this.tryRun(topic, data, listener)));
            for (const item of result) {
                if (item.status === 'rejected') {
                    this.logger.error(`fire event ${topic}:${data} error: ${item.reason}`);
                }
            }
        }
    }
    addWildCardTopic(topic) {
        this.wildCardTopics.add(topic);
        return {
            dispose: () => {
                this.wildCardTopics.delete(topic);
            },
        };
    }
    onEvent(event, listener) {
        const index = event.indexOf(':');
        let topic;
        let data;
        if (index === -1) {
            topic = event;
            data = '';
        }
        else {
            topic = event.substr(0, index);
            data = event.substr(index + 1);
        }
        return this.addListener(topic, {
            topic,
            data,
            execute: listener,
        });
    }
    /**
     * 为了性能考虑，
     * 对于接受通配符的topic，以topic为单位存储listener
     * 对于不接受通配符的topic，直接以event作为单位存储listener
     * @param topic
     * @param listener
     */
    addListener(topic, listener) {
        this.collectTopicData.set(listener.topic, listener.data);
        if (this.wildCardTopics.has(topic)) {
            if (!this.eventListeners.has(topic)) {
                this.eventListeners.set(topic, []);
            }
            this.eventListeners.get(topic).push(listener);
            return {
                dispose: () => {
                    const index = this.eventListeners.get(topic).indexOf(listener);
                    if (index !== -1) {
                        this.eventListeners.get(topic).splice(index, 1);
                    }
                },
            };
        }
        else {
            const event = topic + ':' + listener.data;
            if (!this.eventListeners.has(event)) {
                this.eventListeners.set(event, []);
            }
            this.eventListeners.get(event).push(listener);
            return {
                dispose: () => {
                    const index = this.eventListeners.get(event).indexOf(listener);
                    if (index !== -1) {
                        this.eventListeners.get(event).splice(index, 1);
                    }
                },
            };
        }
    }
    async tryRun(topic, data, listener) {
        if (this.wildCardTopics.has(topic)) {
            if ((0, picomatch_1.default)(listener.data)(data)) {
                await listener.execute();
            }
        }
        else {
            await listener.execute();
        }
    }
};
exports.ActivationEventServiceImpl = ActivationEventServiceImpl;
tslib_1.__decorate([
    (0, di_1.Autowired)(ide_core_common_1.ILogger),
    tslib_1.__metadata("design:type", Object)
], ActivationEventServiceImpl.prototype, "logger", void 0);
exports.ActivationEventServiceImpl = ActivationEventServiceImpl = tslib_1.__decorate([
    (0, di_1.Injectable)(),
    tslib_1.__metadata("design:paramtypes", [])
], ActivationEventServiceImpl);
//# sourceMappingURL=activation.service.js.map