"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Fdc3Service = void 0;
const Fdc3Context_1 = require("../../PredefinedConfig/Common/Fdc3Context");
const Fdc3Intent_1 = require("../../PredefinedConfig/Common/Fdc3Intent");
class Fdc3Service {
    constructor(adaptableApi) {
        var _a, _b, _c, _d, _e, _f;
        this.adaptableApi = adaptableApi;
        this.contextHandlerSubscriptions = [];
        this.intentHandlerSubscriptions = [];
        this.loggedAgentError = false;
        // 1. Subscribe to FDC3 events
        const adaptableHandleIntentFn = (_a = this.getFdc3Options().intents) === null || _a === void 0 ? void 0 : _a.handleIntent;
        const listenForIntents = (_c = (_b = this.getFdc3Options().intents) === null || _b === void 0 ? void 0 : _b.listensFor) !== null && _c !== void 0 ? _c : [];
        if (listenForIntents.length) {
            if (!adaptableHandleIntentFn) {
                this.adaptableApi.logError(`Following FDC3 Intent Listener(s) have been provided but no 'handleIntent' function has been supplied in the FDC3 Options`, listenForIntents);
            }
            listenForIntents.forEach((intent) => {
                var _a;
                this.adaptableApi.logInfo(`Listening for FDC3 Intent: ${intent}`);
                (_a = this.getDesktopAgent()) === null || _a === void 0 ? void 0 : _a.addIntentListener(intent, (context, metadata) => {
                    this.logFdc3Event('IN', `Intent`, JSON.stringify(context));
                    const fnContext = Object.assign(Object.assign({}, this.adaptableApi.internalApi.buildBaseContext()), { context,
                        intent,
                        metadata });
                    adaptableHandleIntentFn === null || adaptableHandleIntentFn === void 0 ? void 0 : adaptableHandleIntentFn(fnContext);
                    const payload = Object.assign(Object.assign({}, this.adaptableApi.internalApi.buildBaseContext()), { direction: 'received', eventType: 'IntentRaised', intent,
                        context,
                        metadata });
                    this.adaptableApi.eventApi.emit('Fdc3Message', payload);
                }).then((listener) => this.intentHandlerSubscriptions.push(listener));
            });
        }
        const adaptableHandleContextFn = (_d = this.getFdc3Options().contexts) === null || _d === void 0 ? void 0 : _d.handleContext;
        const listenForContexts = (_f = (_e = this.getFdc3Options().contexts) === null || _e === void 0 ? void 0 : _e.listensFor) !== null && _f !== void 0 ? _f : [];
        if (listenForContexts.length) {
            if (!adaptableHandleContextFn) {
                this.adaptableApi.logError(`Following FDC3 Context Listener(s) have been provided but no 'handleContext' function has been supplied in the FDC3 Options`, listenForContexts);
            }
            listenForContexts.forEach((contextType) => {
                var _a;
                this.adaptableApi.logInfo(`Listening for FDC3 Context: ${contextType}`);
                (_a = this.getDesktopAgent()) === null || _a === void 0 ? void 0 : _a.addContextListener(contextType, (context, metadata) => {
                    this.logFdc3Event('IN', `Context`, JSON.stringify(context));
                    const fnContext = Object.assign(Object.assign({}, this.adaptableApi.internalApi.buildBaseContext()), { context,
                        metadata });
                    adaptableHandleContextFn === null || adaptableHandleContextFn === void 0 ? void 0 : adaptableHandleContextFn(fnContext);
                    const payload = Object.assign(Object.assign({}, this.adaptableApi.internalApi.buildBaseContext()), { direction: 'received', eventType: 'ContextBroadcast', context,
                        metadata });
                    this.adaptableApi.eventApi.emit('Fdc3Message', payload);
                }).then((listener) => this.contextHandlerSubscriptions.push(listener));
            });
        }
        // 2. Init UI Controls default configuration
        this.uiControlsDefaultConfiguration = this.buildUiControlsDefaultConfiguration();
    }
    getUiControlsDefaultConfiguration() {
        return this.uiControlsDefaultConfiguration;
    }
    getDesktopAgent() {
        if (globalThis.fdc3 == null && !this.loggedAgentError) {
            this.loggedAgentError = true;
            this.adaptableApi.consoleError('FDC3 Desktop Agent not found. This should be provided by the wrapper application.');
        }
        return globalThis.fdc3;
    }
    destroy() {
        this.contextHandlerSubscriptions.forEach((subscription) => subscription.unsubscribe());
        this.intentHandlerSubscriptions.forEach((subscription) => subscription.unsubscribe());
    }
    async raiseIntent(intent, context, app) {
        if (!this.getDesktopAgent()) {
            return;
        }
        try {
            this.logFdc3Event('OUT', `raise ${intent}`, JSON.stringify(context));
            const payload = Object.assign(Object.assign({}, this.adaptableApi.internalApi.buildBaseContext()), { direction: 'sent', eventType: 'RaiseIntent', intent,
                context,
                app });
            this.adaptableApi.eventApi.emit('Fdc3Message', payload);
            const intentResolution = await this.getDesktopAgent().raiseIntent(intent, context, app);
            this.logFdc3Event('IN', `IntentResolution`, intentResolution.intent);
            this.getFdc3Api().internalApi.handleIntentResolution(intentResolution, context, intent, app);
            return intentResolution;
        }
        catch (error) {
            this.logFdc3Error(error);
        }
    }
    async raiseIntentForContext(context, app) {
        if (!this.getDesktopAgent()) {
            return;
        }
        try {
            this.logFdc3Event('OUT', `raise for context`, JSON.stringify(context));
            const payload = Object.assign(Object.assign({}, this.adaptableApi.internalApi.buildBaseContext()), { direction: 'sent', eventType: 'RaiseIntentForContext', context,
                app });
            this.adaptableApi.eventApi.emit('Fdc3Message', payload);
            const intentResolution = await this.getDesktopAgent().raiseIntentForContext(context, app);
            this.logFdc3Event('IN', `IntentResolution`, intentResolution.intent);
            this.getFdc3Api().internalApi.handleIntentResolution(intentResolution, context, null, app);
            return intentResolution;
        }
        catch (error) {
            this.logFdc3Error(error);
        }
    }
    broadcast(context) {
        if (!this.getDesktopAgent()) {
            return;
        }
        try {
            this.logFdc3Event('OUT', `broadcast`, JSON.stringify(context));
            const payload = Object.assign(Object.assign({}, this.adaptableApi.internalApi.buildBaseContext()), { direction: 'sent', eventType: 'BroadcastMessage', context });
            this.adaptableApi.eventApi.emit('Fdc3Message', payload);
            return this.getDesktopAgent().broadcast(context);
        }
        catch (error) {
            this.logFdc3Error(error);
        }
    }
    logFdc3Event(type, ...params) {
        if (!this.getFdc3Options().enableLogging) {
            return;
        }
        this.adaptableApi.consoleLog(`FDC3::${type} - `, params.join(' : '));
    }
    logFdc3Error(error) {
        this.adaptableApi.consoleError(`FDC3 error`, error);
        this.adaptableApi.alertApi.showAlertError('FDC3 Error', 'See console for details');
    }
    getFdc3Api() {
        return this.adaptableApi.fdc3Api;
    }
    getFdc3Options() {
        return this.adaptableApi.optionsApi.getFdc3Options();
    }
    buildUiControlsDefaultConfiguration() {
        var _a, _b;
        const adaptableDefaultContextIcons = Object.keys(Fdc3Context_1.ContextConfiguration).reduce((contextsMapping, contextType) => {
            contextsMapping[contextType] = {
                icon: {
                    name: Fdc3Context_1.ContextConfiguration[contextType].icon,
                },
            };
            return contextsMapping;
        }, {});
        const adaptableDefaultIntentIcons = Object.keys(Fdc3Intent_1.Fdc3IntentConfiguration).reduce((intentsMapping, intentType) => {
            intentsMapping[intentType] = {
                icon: {
                    name: Fdc3Intent_1.Fdc3IntentConfiguration[intentType].icon,
                },
            };
            return intentsMapping;
        }, {});
        // merge adaptable defaults with (optional) user provided configuration
        return {
            contexts: Object.assign(Object.assign({}, adaptableDefaultContextIcons), (_a = this.getFdc3Options().uiControlsDefaultConfiguration) === null || _a === void 0 ? void 0 : _a.contexts),
            intents: Object.assign(Object.assign({}, adaptableDefaultIntentIcons), (_b = this.getFdc3Options().uiControlsDefaultConfiguration) === null || _b === void 0 ? void 0 : _b.intents),
        };
    }
}
exports.Fdc3Service = Fdc3Service;
