"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Fdc3Service = void 0;
const Fdc3Context_1 = require("../../AdaptableState/Common/Fdc3Context");
const Fdc3Intent_1 = require("../../AdaptableState/Common/Fdc3Intent");
class Fdc3Service {
    constructor(adaptableApi) {
        this.adaptableApi = adaptableApi;
        this.contextHandlerSubscriptions = [];
        this.intentHandlerSubscriptions = [];
        this.loggedAgentError = false;
        // 1. Subscribe to FDC3 events
        const adaptableHandleIntentFn = this.getFdc3Options().intents?.handleIntent;
        const listenForIntents = this.getFdc3Options().intents?.listensFor ?? [];
        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) => {
                this.adaptableApi.logInfo(`Listening for FDC3 Intent: ${intent}`);
                this.getDesktopAgent()
                    ?.addIntentListener(intent, (context, metadata) => {
                    this.logFdc3Event('IN', `Intent`, JSON.stringify(context));
                    const fnContext = {
                        ...this.adaptableApi.internalApi.buildBaseContext(),
                        context,
                        intent,
                        metadata,
                    };
                    adaptableHandleIntentFn?.(fnContext);
                    const payload = {
                        ...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 = this.getFdc3Options().contexts?.handleContext;
        const listenForContexts = this.getFdc3Options().contexts?.listensFor ?? [];
        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) => {
                this.adaptableApi.logInfo(`Listening for FDC3 Context: ${contextType}`);
                this.getDesktopAgent()
                    ?.addContextListener(contextType, (context, metadata) => {
                    this.logFdc3Event('IN', `Context`, JSON.stringify(context));
                    const fnContext = {
                        ...this.adaptableApi.internalApi.buildBaseContext(),
                        context,
                        metadata,
                    };
                    adaptableHandleContextFn?.(fnContext);
                    const payload = {
                        ...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 = {
                ...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 = {
                ...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, channel) {
        if (!this.getDesktopAgent()) {
            return;
        }
        try {
            this.logFdc3Event('OUT', `broadcast`, JSON.stringify(context));
            const payload = {
                ...this.adaptableApi.internalApi.buildBaseContext(),
                direction: 'sent',
                eventType: 'BroadcastMessage',
                context,
            };
            this.adaptableApi.eventApi.emit('Fdc3Message', payload);
            if (channel) {
                return channel.broadcast(context);
            }
            else {
                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() {
        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: {
                ...adaptableDefaultContextIcons,
                ...this.getFdc3Options().uiControlsDefaultConfiguration?.contexts,
            },
            intents: {
                ...adaptableDefaultIntentIcons,
                ...this.getFdc3Options().uiControlsDefaultConfiguration?.intents,
            },
        };
    }
}
exports.Fdc3Service = Fdc3Service;
