import { EventEmitter } from 'ee-ts';
import { formatWebSocketUri } from './utils';
const SOCKET_URL_SUFFIX = 'websocket';
const spamData = `\u0000\u0000\u0000\u0000`;
/**
 * Клас для роботи з WebSocket-з'єднанням.
 */
export class Socket extends EventEmitter {
    /**
     * Конструктор класу Socket.
     * @param host Хост для підключення.
     * @param appName Імя підключення.
     */
    constructor(host, appName, appVer) {
        super();
        this.host = host;
        this.appName = appName;
        this.appVer = appVer;
        // this.socket = null
    }
    /**
     * Встановлює з'єднання з WebSocket.
     * @param token Токен для авторизації.
     */
    connect(token) {
        this.socket = new WebSocket(`${formatWebSocketUri(this.host)}/${SOCKET_URL_SUFFIX}?application_name=${this.appName ||
            'webitel_sdk'}&ver=${this.appVer || ''}`);
        this.socket.onclose = (e) => this.onClose(e.code);
        this.socket.onmessage = (e) => this.onMessage(e.data);
        this.socket.onopen = () => this.onOpen();
    }
    /**
     * Відправляє запит через WebSocket.
     * @param request Запит, який необхідно відправити.
     * @returns Ніколи або null.
     */
    send(request) {
        this.socket.send(JSON.stringify(request));
        return null;
    }
    /**
     * Закриває WebSocket-з'єднання.
     * @param code Код закриття з'єднання (необов'язково).
     */
    close(code) {
        this.socket.close(code || 1000);
        delete this.socket;
        this.onClose(code || 1000);
    }
    /**
     * Викликається при відкритті з'єднання.
     * Генерує подію 'open'.
     * @private
     */
    onOpen() {
        this.emit('open');
    }
    /**
     * Викликається при закритті з'єднання.
     * Генерує подію 'close' та очищає слухачів подій.
     * @param code Код закриття з'єднання.
     * @private
     */
    onClose(code) {
        this.emit('close', code);
        this.off('*');
    }
    /**
     * Викликається при отриманні повідомлення.
     * Парсує дані повідомлення і генерує подію 'message'.
     * @param data Дані повідомлення у форматі рядка.
     * @private
     */
    onMessage(data) {
        if (data !== spamData) {
            const message = JSON.parse(data);
            this.emit('message', message);
        }
    }
}
//# sourceMappingURL=socket.js.map