/* global ga */

(function(ctx) {
    /**
     *
     */
    function Analytics(options) {
        /* eslint-disable */

        if (!options.googleAnalyticsTrackingId) {
            console.log(
                'Failed to initialize Google Analytics handler, no tracking ID');
             return;
        }

        /**
         * Google Analytics
         * TODO: Keep this local, there's no need to add it to window.
         */
        (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
        })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
        ga('create', options.googleAnalyticsTrackingId, 'auto');
        ga('send', 'pageview');

        /* eslint-enable */
    }

    /**
     * Extracts the integer to use for a Google Analytics event's value field
     * from a lib-jitsi-meet analytics event.
     * @param {Object} event - The lib-jitsi-meet analytics event.
     * @returns {Object} - The integer to use for the 'value' of a Google
     * Analytics event.
     * @private
     */
    Analytics.prototype._extractAction = function(event) {
        // Page events have a single 'name' field.
        if (event.type === 'page') {
            return event.name;
        }

        // All other events have action, actionSubject, and source fields. All
        // three fields are required, and the often jitsi-meet and
        // lib-jitsi-meet use the same value when separate values are not
        // necessary (i.e. event.action == event.actionSubject).
        // Here we concatenate these three fields, but avoid adding the same
        // value twice, because it would only make the GA event's action harder
        // to read.
        let action = event.action;

        if (event.actionSubject && event.actionSubject !== event.action) {
            // Intentionally use string concatenation as analytics needs to
            // work on IE but this file does not go through babel. For some
            // reason disabling this globally for the file does not have an
            // effect.
            // eslint-disable-next-line prefer-template
            action = event.actionSubject + '.' + action;
        }
        if (event.source && event.source !== event.action
                && event.source !== event.action) {
            // eslint-disable-next-line prefer-template
            action = event.source + '.' + action;
        }

        return action;
    };

    /**
     * Extracts the integer to use for a Google Analytics event's value field
     * from a lib-jitsi-meet analytics event.
     * @param {Object} event - The lib-jitsi-meet analytics event.
     * @returns {Object} - The integer to use for the 'value' of a Google
     * Analytics event, or NaN if the lib-jitsi-meet event doesn't contain a
     * suitable value.
     * @private
     */
    Analytics.prototype._extractValue = function(event) {
        let value = event && event.attributes && event.attributes.value;

        // Try to extract an integer from the "value" attribute.
        value = Math.round(parseFloat(value));

        return value;
    };

    /**
     * Extracts the string to use for a Google Analytics event's label field
     * from a lib-jitsi-meet analytics event.
     * @param {Object} event - The lib-jitsi-meet analytics event.
     * @returns {string} - The string to use for the 'label' of a Google
     * Analytics event.
     * @private
     */
    Analytics.prototype._extractLabel = function(event) {
        let label = '';

        // The label field is limited to 500B. We will concatenate all
        // attributes of the event, except the user agent because it may be
        // lengthy and is probably included from elsewhere.
        for (const property in event.attributes) {
            if (property !== 'permanent_user_agent'
                && property !== 'permanent_callstats_name'
                && event.attributes.hasOwnProperty(property)) {
                // eslint-disable-next-line prefer-template
                label += property + '=' + event.attributes[property] + '&';
            }
        }

        if (label.length > 0) {
            label = label.slice(0, -1);
        }

        return label;
    };

    /**
     * This is the entry point of the API. The function sends an event to
     * google analytics. The format of the event is described in
     * AnalyticsAdapter in lib-jitsi-meet.
     * @param {Object} event - the event in the format specified by
     * lib-jitsi-meet.
     */
    Analytics.prototype.sendEvent = function(event) {
        if (!event || !ga) {
            return;
        }

        const ignoredEvents
            = [ 'e2e_rtt', 'rtp.stats', 'rtt.by.region', 'available.device',
                'stream.switch.delay', 'ice.state.changed', 'ice.duration' ];

        // Temporary removing some of the events that are too noisy.
        if (ignoredEvents.indexOf(event.action) !== -1) {
            return;
        }

        const gaEvent = {
            'eventCategory': 'jitsi-meet',
            'eventAction': this._extractAction(event),
            'eventLabel': this._extractLabel(event)
        };
        const value = this._extractValue(event);

        if (!isNaN(value)) {
            gaEvent.eventValue = value;
        }

        ga('send', 'event', gaEvent);
    };

    if (typeof ctx.JitsiMeetJS === 'undefined') {
        ctx.JitsiMeetJS = {};
    }
    if (typeof ctx.JitsiMeetJS.app === 'undefined') {
        ctx.JitsiMeetJS.app = {};
    }
    if (typeof ctx.JitsiMeetJS.app.analyticsHandlers === 'undefined') {
        ctx.JitsiMeetJS.app.analyticsHandlers = [];
    }
    ctx.JitsiMeetJS.app.analyticsHandlers.push(Analytics);
})(window);
/* eslint-enable prefer-template */