"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const jssip = require("jssip");
const events = require("events");
const SipSession_1 = require("./SipSession");
function normalizeNumber(number) {
    // Don't normalize if a SIP/TEL URI.
    if (/^(sips?|tel):/i.test(number)) {
        return number;
    }
    // Don't normalize if it wanted to be a SIP URI.
    else if (/@/i.test(number)) {
        return number;
    }
    // Otherwise remove spaces and some symbols.
    else {
        return number.replace(/[()\-. ]*/g, '');
    }
}
class SipClient extends events.EventEmitter {
    constructor(options) {
        super();
        const { client, stunServers = ['stun:stun.l.google.com:19302'], wsUri = 'wss://teams.callable.io:8443', debug = false, } = options;
        this._pcConfig = {
            pcConfig: {
                iceServers: [
                    {
                        urls: stunServers,
                    },
                ],
            },
            wsUri: wsUri,
        };
        this._debug && console.log({ client: client, config: this._pcConfig }, 'creating a sip client');
        const socket = new jssip.WebSocketInterface(this._pcConfig.wsUri);
        const uri = `sip:${client.fullUsername}`;
        this._ua = new jssip.UA({
            uri,
            password: client.password,
            display_name: client.name,
            sockets: [socket],
            register: true,
        });
        this._ua.on('connecting', (data) => {
            const { socket, attempts } = data;
            const payload = { client, socket, attempts };
            this.emit('connecting', payload);
        });
        this._ua.on('connected', (data) => {
            const { socket } = data;
            const payload = { client, socket };
            this.emit('connected', payload);
        });
        this._ua.on('disconnected', (data) => {
            const { socket, error, code, reason } = data;
            const payload = { client, socket, error, code, reason };
            this.emit('disconnected', payload);
        });
        this._ua.on('registered', (data) => {
            const { response } = data;
            const payload = { response, client };
            this.emit('registered', payload);
        });
        this._ua.on('unregistered', (data) => {
            const { response, cause } = data;
            const payload = { response, cause, client };
            this.emit('unregistered', payload);
        });
        this._ua.on('registrationFailed', (data) => {
            const { response, cause } = data;
            const payload = { response, cause, client };
            this.emit('registrationFailed', payload);
        });
        this._ua.on('newRTCSession', (data) => {
            let rtcSession = data.session;
            this._onSession(rtcSession);
        });
    }
    start() {
        this._debug && console.log('start()');
        this._ua.start();
    }
    stop() {
        this._debug && console.log('stop()');
        this._ua.stop();
    }
    call(number) {
        this._debug && console.log(`call() [number: ${number}]`);
        let normalizedNumber = normalizeNumber(number);
        const calloptions = {
            mediaConstraints: { audio: true, video: false },
            pcConfig: this._pcConfig,
        };
        this._ua.call(normalizedNumber, calloptions);
    }
    _onSession(rtcSession) {
        let session = new SipSession_1.default(rtcSession, {
            pcConfig: this._pcConfig,
            onSession: this._onSession.bind(this),
            debug: this._debug,
        });
        this.emit('session', session);
    }
}
exports.default = SipClient;
