/*
 * Copyright 2017 IBM Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/* eslint-disable no-dupe-class-members */
import { EventEmitter } from 'events';
import { ExecType } from '../models/command';
import { getPrimaryTabId } from '../webapp/tab';
const eventChannelUnsafe = new EventEmitter();
eventChannelUnsafe.setMaxListeners(100);
export default eventChannelUnsafe;
class EventBusBase {
    constructor() {
        const eventBus = new EventEmitter();
        eventBus.setMaxListeners(100);
        this.eventBus = eventBus;
    }
}
class WriteEventBus extends EventBusBase {
    emit(channel, args) {
        return this.eventBus.emit(channel, args);
    }
    emitCommandEvent(which, event) {
        this.eventBus.emit(`/command/${which}`, event);
        if (event.execType !== ExecType.Nested) {
            this.eventBus.emit(`/command/${which}/fromuser`, event);
            this.eventBus.emit(`/command/${which}/fromuser/${event.tab.uuid}`, event);
            const primary = getPrimaryTabId(event.tab);
            if (event.tab.uuid !== primary) {
                this.eventBus.emit(`/command/${which}/fromuser/${primary}`, event);
            }
            this.eventBus.emit(`/command/${which}/fromuser/${primary}/type/${event.execType}`, event);
        }
    }
    emitCommandStart(event) {
        this.emitCommandEvent('start', event);
    }
    emitCommandComplete(event) {
        this.emitCommandEvent('complete', event);
        if (event.execType !== ExecType.Nested) {
            this.eventBus.emit(`/command/complete/fromuser/${event.responseType}`, event);
            this.eventBus.emit(`/command/complete/fromuser/${event.responseType}/${event.tab.uuid}`, event);
            const primary = getPrimaryTabId(event.tab);
            if (primary !== event.tab.uuid) {
                this.eventBus.emit(`/command/complete/fromuser/${event.responseType}/${primary}`, event);
            }
        }
    }
    emitWithTabId(channel, tabId, tab) {
        this.eventBus.emit(`${channel}/${tabId}`, tabId, tab);
    }
}
class ReadEventBus extends WriteEventBus {
    on(channel, listener) {
        return this.eventBus.on(channel, listener);
    }
    onCommand(which, splitId, splitHandler, tabId, tabHandler = splitHandler) {
        this.eventBus.on(`/command/${which}/fromuser/${splitId}`, splitHandler);
        if (tabId) {
            this.eventBus.on(`/command/${which}/fromuser/${tabId}/type/${ExecType.ClickHandler}`, tabHandler);
        }
    }
    offCommand(which, splitId, splitHandler, tabId, tabHandler = splitHandler) {
        this.eventBus.off(`/command/${which}/fromuser/${splitId}`, splitHandler);
        if (tabId) {
            this.eventBus.off(`/command/${which}/fromuser/${tabId}/type/${ExecType.ClickHandler}`, tabHandler);
        }
    }
    onAnyCommandStart(handler) {
        this.eventBus.on('/command/start/fromuser', handler);
    }
    offAnyCommandStart(handler) {
        this.eventBus.on('/command/start/fromuser', handler);
    }
    onAnyCommandComplete(handler) {
        this.eventBus.on('/command/complete/fromuser', handler);
    }
    offAnyCommandComplete(handler) {
        this.eventBus.on('/command/complete/fromuser', handler);
    }
    onCommandStart(splitId, splitHandler, tabId, tabHandler = splitHandler) {
        this.onCommand('start', splitId, splitHandler, tabId, tabHandler);
    }
    onceCommandStarts(tabId, handler) {
        this.eventBus.once(`/command/start/fromuser/${tabId}`, handler);
    }
    onResponseType(responseType, splitId, splitHandler, tabId, tabHandler = splitHandler) {
        this.eventBus.on(`/command/complete/fromuser/${responseType}/${splitId}`, splitHandler);
        if (tabId) {
            this.eventBus.on(`/command/complete/fromuser/${responseType}/${tabId}`, tabHandler);
        }
    }
    offResponseType(responseType, splitId, splitHandler, tabId, tabHandler = splitHandler) {
        this.eventBus.off(`/command/complete/fromuser/${responseType}/${splitId}`, splitHandler);
        if (tabId) {
            this.eventBus.off(`/command/complete/fromuser/${responseType}/${tabId}`, tabHandler);
        }
    }
    onScalarResponse(splitId, splitHandler, tabId, tabHandler = splitHandler) {
        this.onResponseType('ScalarResponse', splitId, splitHandler, tabId, tabHandler);
    }
    offScalarResponse(splitId, splitHandler, tabId, tabHandler = splitHandler) {
        this.offResponseType('ScalarResponse', splitId, splitHandler, tabId, tabHandler);
    }
    onMultiModalResponse(tabId, handler) {
        this.onResponseType('MultiModalResponse', tabId, handler);
    }
    offMultiModalResponse(tabId, handler) {
        this.offResponseType('MultiModalResponse', tabId, handler);
    }
    onNavResponse(tabId, handler) {
        this.onResponseType('NavResponse', tabId, handler);
    }
    offNavResponse(tabId, handler) {
        this.offResponseType('NavResponse', tabId, handler);
    }
    onCommandComplete(splitId, splitHandler, tabId, tabHandler = splitHandler) {
        this.onCommand('complete', splitId, splitHandler, tabId, tabHandler);
    }
    offCommandStart(splitId, splitHandler, tabId, tabHandler = splitHandler) {
        this.offCommand('start', splitId, splitHandler, tabId, tabHandler);
    }
    offCommandComplete(splitId, splitHandler, tabId, tabHandler = splitHandler) {
        this.offCommand('complete', splitId, splitHandler, tabId, tabHandler);
    }
    onWithTabId(channel, tabId, listener) {
        this.eventBus.on(`${channel}/${tabId}`, listener);
    }
    offWithTabId(channel, tabId, listener) {
        this.eventBus.off(`${channel}/${tabId}`, listener);
    }
    onceWithTabId(channel, tabId, listener) {
        this.eventBus.once(`${channel}/${tabId}`, listener);
    }
    once(channel, listener) {
        return this.eventBus.once(channel, listener);
    }
}
class EventBus extends ReadEventBus {
}
export const eventBus = new EventBus();
/**
 * Hook an event listener up to tab events.
 *
 */
export function wireToTabEvents(listener) {
    eventBus.on('/tab/new', listener);
    eventBus.on('/tab/switch/request', listener);
}
/**
 * Hook an event listener up to the family of standard user
 * interaction events.
 *
 */
export function wireToStandardEvents(listener) {
    wireToTabEvents(listener);
    eventBus.onAnyCommandComplete(() => listener());
}
//# sourceMappingURL=events.js.map