Source: Campaigns/campaigns.js

/**
 * @class
 * @classdesc Plugin used to manage campaigns marketing (which can be the origin of visits)
 * @name Campaigns
 * @memberof ATInternet.Tracker.Plugins
 * @type {function}
 * @param tag {object} Instance of the Tag used
 * @public
 */
ATInternet.Tracker.Plugins.Campaigns = function (tag) {
    'use strict';

    tag.setConfig('visitLifetime', dfltGlobalCfg.visitLifetime, true);
    tag.setConfig('redirectionLifetime', dfltGlobalCfg.redirectionLifetime, true);
    var confCampaigns = {},
        _set_storage_method,
        _get_storage_method;
    tag.configPlugin('Campaigns', dfltPluginCfg || {}, function (newConf) {
        confCampaigns = newConf;
    });

    // Input values
    var _in_atredir_gopc,
        _in_atredir_gopc_err,
        _in_atredir_camp,
        _in_atsession_histo_camp,
        _in_atreman_camp,
        _in_atreman_date,
        _in_url_xtor,
        _in_url_xtdt,
        _in_url_xts,
        _in_tag_forcedCampaign;
    // Context values
    var _isRedirection,
        _isGopc,
        _isGopcErr;

    /**
     * Defines labels to use for unique persistence
     * @memberof ATInternet.Tracker.Plugins.Campaigns#
     * @function
     * @private
     */
    var _defineUniquePersistence = function () {
        _set_storage_method = 'set' + (confCampaigns.domainAttribution ? '' : 'Private');
        _get_storage_method = 'get' + (confCampaigns.domainAttribution ? '' : 'Private');
    };

    /**
     * Object used to manage campaigns from URL query
     * @name Campaigns
     * @memberof ATInternet.Tracker.Plugins.Campaigns#
     * @inner
     * @type {function}
     * @property {function} SponsoredLinks Tag helper, see details here {@link ATInternet.Tracker.Tag#Campaigns.SponsoredLinks}
     * @property {function} Email Tag helper, see details here {@link ATInternet.Tracker.Tag#Campaigns.Email}
     * @property {function} Affiliate Tag helper, see details here {@link ATInternet.Tracker.Tag#Campaigns.Affiliate}
     * @property {function} Display Tag helper, see details here {@link ATInternet.Tracker.Tag#Campaigns.Display}
     * @property {function} Custom Tag helper, see details here {@link ATInternet.Tracker.Tag#Campaigns.Custom}
     * @property {object} medium Tag helper, see details here {@link ATInternet.Tracker.Tag#Campaigns.medium}
     * @private
     */
    var Campaigns = function () {
        /**
         * Get a formatted campaign identifier
         * @memberof ATInternet.Tracker.Plugins.Campaigns#
         * @function
         * @param campaignIdLabel {string}
         * @return {string}
         * @private
         */
        var _getCampaignIdLabel = function (campaignIdLabel) {
            var _idLabel = '';
            if (campaignIdLabel) {
                if (!isNaN(campaignIdLabel) || // 456
                    (campaignIdLabel.search(/^\[(.*?)\]$/g) !== -1) || // [test]
                    (campaignIdLabel.search(/^\d+\[(.*?)\]$/g) !== -1)) { // 456[test]
                    _idLabel = campaignIdLabel;
                } else {
                    _idLabel = '[' + campaignIdLabel + ']';
                }
            }
            return _idLabel;
        };
        /**
         * Add square brackets if the campaign label contains dash (used as a separator)
         * @memberof ATInternet.Tracker.Plugins.Campaigns#
         * @function
         * @param campaignLabel {string}
         * @return {string}
         * @private
         */
        var _getCampaignLabel = function (campaignLabel) {
            var _label = campaignLabel;
            if (campaignLabel.search(/[-]/g) !== -1 && campaignLabel.search(/^\[(.*?)\]$/g) === -1) {
                _label = '[' + campaignLabel + ']';
            }
            return _label;
        };
        /**
         * Remove the dash symbols at the end of the xtor label
         * @memberof ATInternet.Tracker.Plugins.Campaigns#
         * @function
         * @param xtor {string}
         * @return {string}
         * @private
         */
        var _cleanCampaignLabel = function (xtor) {
            while (xtor.charAt(xtor.length - 1) === '-') {
                xtor = xtor.substring(0, xtor.length - 1);
            }
            return xtor;
        };
        /**
         * SponsoredLinks
         * @alias Campaigns.SponsoredLinks
         * @memberof! ATInternet.Tracker.Plugins.Campaigns#
         * @function
         * @public
         */
        this.SponsoredLinks = function () {
            var plaforms = {
                'google': 'goo',
                'yahoo': 'ysm',
                'miva': 'miv',
                'orange': 'wan',
                'msn': 'msn',
                'mirago': 'mir',
                'sklik': 'skl',
                'adfox': 'adf',
                'etarget': 'etg',
                'yandex': 'yan',
                'ebay': 'eba',
                'searchalliance': 'sal',
                'bing': 'bin',
                'naver': 'nav',
                'baidu': 'bdu',
                'qwant': 'qwt',
                'waze': 'waz',
                'amazon': 'amz'
            };
            var networks = {
                'search': 's',
                'content': 'c'
            };
            this.atMedium = 'sl';
            this.atCampaign = '';
            this.atPlatform = '';
            this.atCreation = '';
            this.atVariant = '';
            this.atNetwork = '';
            this.atTerm = '';
            this.format = function () {
                var xtor = 'sec';
                var B = _getCampaignIdLabel(this.atCampaign);
                var C = plaforms[this.atPlatform] || _getCampaignLabel(this.atPlatform);
                var D = _getCampaignIdLabel(this.atCreation);
                var E = _getCampaignIdLabel(this.atVariant);
                var F = networks[this.atNetwork] || _getCampaignLabel(this.atNetwork);
                var G = _getCampaignIdLabel(this.atTerm);
                xtor += '-' + B + '-' + C + '-' + D + '-' + E + '-' + F + '-' + G;
                return _cleanCampaignLabel(xtor);
            };
            this.setProperties = function (href) {
                this.atCampaign = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'campaign', href) || '';
                this.atPlatform = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'platform', href) || '';
                this.atCreation = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'creation', href) || '';
                this.atVariant = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'variant', href) || '';
                this.atNetwork = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'network', href) || '';
                this.atTerm = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'term', href) || '';
                tag.setContext('campaigns_events', {
                    "$": this.atMedium,
                    "campaign": this.atCampaign,
                    "platform": this.atPlatform,
                    "creation": this.atCreation,
                    "variant": this.atVariant,
                    "network": this.atNetwork,
                    "term": this.atTerm
                });
            };
            // For unit tests on private elements !!!
            /* @if test */
            this.plaforms = plaforms;
            this.networks = networks;
            /* @endif */
        };
        /**
         * Email
         * @alias Campaigns.Email
         * @memberof! ATInternet.Tracker.Plugins.Campaigns#
         * @function
         * @public
         */
        this.Email = function () {
            var types = {
                'acquisition': 'erec',
                'retention': 'epr',
                'promotion': 'es'
            };
            this.atMedium = 'email';
            this.atEmailtype = '';
            this.atCampaign = '';
            this.atCreation = '';
            this.atSendDate = '';
            this.atLink = '';
            this.atRecipientId = '';
            this.atRecipientList = '';
            this.atSendTime = '';
            this.format = function () {
                var xtor = types[this.atEmailtype] || types.promotion;
                var B = _getCampaignIdLabel(this.atCampaign);
                var C = _getCampaignIdLabel(this.atCreation);
                var D = _getCampaignLabel(this.atSendDate);
                var E = _getCampaignIdLabel(this.atLink);
                var F = _getCampaignLabel(this.atRecipientId) + (this.atRecipientList ? '@' + _getCampaignLabel(this.atRecipientList) : '');
                var G = _getCampaignLabel(this.atSendTime);
                xtor += '-' + B + '-' + C + '-' + D + '-' + E + '-' + F + '-' + G;
                return _cleanCampaignLabel(xtor);
            };
            this.setProperties = function (href) {
                this.atEmailtype = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'emailtype', href) || '';
                this.atCampaign = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'campaign', href) || '';
                this.atCreation = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'creation', href) || '';
                this.atSendDate = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'send_date', href) || '';
                this.atLink = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'link', href) || '';
                this.atRecipientId = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'recipient_id', href) || '';
                this.atRecipientList = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'recipient_list', href) || '';
                this.atSendTime = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'send_time', href) || '';
                tag.setContext('campaigns_events', {
                    "$": this.atMedium,
                    "emailtype": this.atEmailtype,
                    "campaign": this.atCampaign,
                    "creation": this.atCreation,
                    "send_date": this.atSendDate,
                    "link": this.atLink,
                    "recipient_id": this.atRecipientId,
                    "recipient_list": this.atRecipientList,
                    "send_time": this.atSendTime
                });
            };
            // For unit tests on private elements !!!
            /* @if test */
            this.types = types;
            /* @endif */
        };
        /**
         * Affiliate
         * @alias Campaigns.Affiliate
         * @memberof! ATInternet.Tracker.Plugins.Campaigns#
         * @function
         * @public
         */
        this.Affiliate = function () {
            this.atMedium = 'affiliate';
            this.atCampaign = '';
            this.atType = '';
            this.atIdentifier = '';
            this.atFormat = '';
            this.atCreation = '';
            this.atVariant = '';
            this.format = function () {
                var xtor = 'al';
                var B = _getCampaignIdLabel(this.atCampaign);
                var C = _getCampaignIdLabel(this.atType);
                var D = _getCampaignIdLabel(this.atIdentifier);
                var E = _getCampaignIdLabel(this.atFormat);
                var F = _getCampaignIdLabel(this.atCreation);
                var G = _getCampaignIdLabel(this.atVariant);
                xtor += '-' + B + '-' + C + '-' + D + '-' + E + '-' + F + '-' + G;
                return _cleanCampaignLabel(xtor);
            };
            this.setProperties = function (href) {
                this.atCampaign = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'campaign', href) || '';
                this.atType = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'type', href) || '';
                this.atIdentifier = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'identifier', href) || '';
                this.atFormat = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'format', href) || '';
                this.atCreation = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'creation', href) || '';
                this.atVariant = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'variant', href) || '';
                tag.setContext('campaigns_events', {
                    "$": this.atMedium,
                    "campaign": this.atCampaign,
                    "type": this.atType,
                    "identifier": this.atIdentifier,
                    "format": this.atFormat,
                    "creation": this.atCreation,
                    "variant": this.atVariant
                });
            };
        };
        /**
         * Display
         * @alias Campaigns.Display
         * @memberof! ATInternet.Tracker.Plugins.Campaigns#
         * @function
         * @public
         */
        this.Display = function () {
            this.atMedium = 'display';
            this.atCampaign = '';
            this.atCreation = '';
            this.atVariant = '';
            this.atFormat = '';
            this.atChannel = '';
            this.atGeneralPlacement = '';
            this.atDetailPlacement = '';
            this.format = function () {
                var xtor = 'ad';
                var B = _getCampaignIdLabel(this.atCampaign);
                var C = _getCampaignIdLabel(this.atCreation);
                var D = _getCampaignIdLabel(this.atVariant);
                var E = _getCampaignIdLabel(this.atFormat);
                var F = _getCampaignIdLabel(this.atChannel);
                var G = _getCampaignIdLabel(this.atGeneralPlacement);
                var H = _getCampaignIdLabel(this.atDetailPlacement);
                xtor += '-' + B + '-' + C + '-' + D + '-' + E + '-' + F + '-' + G + '-' + H;
                return _cleanCampaignLabel(xtor);
            };
            this.setProperties = function (href) {
                this.atCampaign = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'campaign', href) || '';
                this.atCreation = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'creation', href) || '';
                this.atVariant = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'variant', href) || '';
                this.atFormat = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'format', href) || '';
                this.atChannel = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'channel', href) || '';
                this.atGeneralPlacement = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'general_placement', href) || '';
                this.atDetailPlacement = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'detail_placement', href) || '';
                tag.setContext('campaigns_events', {
                    "$": this.atMedium,
                    "campaign": this.atCampaign,
                    "creation": this.atCreation,
                    "variant": this.atVariant,
                    "format": this.atFormat,
                    "channel": this.atChannel,
                    "general_placement": this.atGeneralPlacement,
                    "detail_placement": this.atDetailPlacement
                });
            };
        };
        /**
         * Custom
         * @alias Campaigns.Custom
         * @memberof! ATInternet.Tracker.Plugins.Campaigns#
         * @function
         * @public
         */
        this.Custom = function () {
            this.atMedium = '';
            this.atCampaign = '';
            this.atCustom1 = '';
            this.atCustom2 = '';
            this.atCustom3 = '';
            this.atCustom4 = '';
            this.format = function () {
                var index = '';
                if (/\d+$/.test(this.atMedium)) {
                    index = /\d+$/.exec(this.atMedium)[0];
                }
                var xtor = 'cs' + index;
                var B = _getCampaignIdLabel(this.atCampaign);
                var C = _getCampaignIdLabel(this.atCustom1);
                var D = _getCampaignIdLabel(this.atCustom2);
                var E = _getCampaignIdLabel(this.atCustom3);
                var F = _getCampaignIdLabel(this.atCustom4);
                xtor += '-' + B + '-' + C + '-' + D + '-' + E + '-' + F;
                return _cleanCampaignLabel(xtor);
            };
            this.setProperties = function (href) {
                this.atMedium = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'medium', href) || '';
                this.atCampaign = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'campaign', href) || '';
                this.atCustom1 = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'custom1', href) || '';
                this.atCustom2 = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'custom2', href) || '';
                this.atCustom3 = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'custom3', href) || '';
                this.atCustom4 = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'custom4', href) || '';
                tag.setContext('campaigns_events', {
                    "$": this.atMedium,
                    "campaign": this.atCampaign,
                    "custom1": this.atCustom1,
                    "custom2": this.atCustom2,
                    "custom3": this.atCustom3,
                    "custom4": this.atCustom4
                });
            };
        };
        /**
         * medium
         * @alias Campaigns.medium
         * @memberof! ATInternet.Tracker.Plugins.Campaigns#
         * @object
         * @public
         */
        this.medium = {
            'sl': this.SponsoredLinks,
            'email': this.Email,
            'affiliate': this.Affiliate,
            'display': this.Display
        };
        // For unit tests on private elements !!!
        /* @if test */
        this._getCampaignIdLabel = _getCampaignIdLabel;
        this._getCampaignLabel = _getCampaignLabel;
        this._cleanCampaignLabel = _cleanCampaignLabel;
        /* @endif */
    };

    /**
     * Set a parameter with its value in campaigns context
     * @memberof ATInternet.Tracker.Plugins.Campaigns#
     * @function
     * @param param {string} Name of the parameter to register
     * @param value {string} Value of the parameter to register
     * @private
     */
    var _setContext = function (param, value) {
        var _context = tag.getContext('campaigns') || {};
        _context[param] = value;
        tag.setContext('campaigns', _context);
    };

    /**
     * Get parameters from query (at_, xtor, utm_, etc.).
     * @memberof ATInternet.Tracker.Plugins.Campaigns#
     * @function
     * @private
     */
    var _getParametersFromQuery = function () {
        var href = tag.utils.getLocation();
        /**
         * Process AT campaign.
         * @function
         * @private
         */
        var _processATCampaign = function () {
            var atMedium = tag.utils.getQueryStringValue(confCampaigns.querystringPrefix + 'medium', href);
            if (atMedium) {
                var campaigns = new Campaigns();
                var mediumObject;
                if (typeof campaigns.medium[atMedium] === 'function') {
                    mediumObject = new campaigns.medium[atMedium]();
                } else {
                    mediumObject = new campaigns.Custom();
                }
                mediumObject.setProperties(href);
                _in_url_xtor = mediumObject.format();
            } else {
                _in_url_xtor = tag.utils.getQueryStringValue('xtor', href);
            }
            _in_url_xtdt = tag.utils.getQueryStringValue('xtdt', href);
            _in_url_xts = tag.utils.getQueryStringValue('xts', href);
        };
        /**
         * Process UTM campaign.
         * @function
         * @private
         */
        var _processUTMCampaign = function () {
            var utmParameters = confCampaigns.UTMParameters;
            var utmParameter;
            for (var i = 0; i < utmParameters.length; i++) {
                utmParameter = tag.utils.getQueryStringValue(utmParameters[i], href);
                utmParameter && _setContext(utmParameters[i], utmParameter);
            }
        };
        _processATCampaign();
        !!confCampaigns.enableUTMTracking && _processUTMCampaign();
    };

    /**
     * Retrieve raw data (in the url, storage or configuration) for the campaigns processing.
     * @memberof ATInternet.Tracker.Plugins.Campaigns#
     * @function
     * @private
     */
    var _retrieveInputValues = function () {
        // Get stored data on redirectionc
        _in_atredir_gopc = tag.storage[_get_storage_method](['atredir', 'gopc']);
        _in_atredir_gopc_err = tag.storage[_get_storage_method](['atredir', 'gopc_err']);
        _in_atredir_camp = tag.storage[_get_storage_method](['atredir', 'camp']);
        // Burn after reading
        tag.storage.del(['atredir', 'gopc']);
        tag.storage.del(['atredir', 'gopc_err']);
        tag.storage.del(['atredir', 'camp']);
        // Get campaigns historic
        _in_atsession_histo_camp = tag.storage[_get_storage_method](['atsession', 'histo_camp']);
        // Get persistent stored data
        _in_atreman_camp = tag.storage[_get_storage_method](['atreman', 'camp']);
        _in_atreman_date = tag.storage[_get_storage_method](['atreman', 'date']);
        // Get parameters from querystring
        _getParametersFromQuery();
        // Get forced campaign from context
        _in_tag_forcedCampaign = tag.getContext("forcedCampaign");
    };

    /**
     * Deduct context from raw information : html/javascript redirection, GOPC and GOPC_ERR
     * @memberof ATInternet.Tracker.Plugins.Campaigns#
     * @function
     * @private
     */
    var _processContextValues = function () {
        _isRedirection = !!tag.getConfig('redirect');
        _isGopc = !!(_in_url_xtor && _in_url_xtdt && _in_url_xts);
        _isGopcErr = false;
        if (_isGopc) {
            var nowInMin = (new Date()).getTime() / 60000;
            _isGopcErr = (
                (!_isRedirection && (_in_url_xts !== tag.getConfig('site'))) ||
                (nowInMin - _in_url_xtdt < 0) ||
                (nowInMin - _in_url_xtdt >= tag.getConfig('visitLifetime'))
            );
        }
    };

    /**
     * Check if a stored data is present and with type object, if not it creates it and return true,
     * if present but with another type it returns false
     * @memberof ATInternet.Tracker.Plugins.Campaigns#
     * @function
     * @param name {string} Name of the stored data you need to check
     * @param options {object} Options of the data to store in case of creation
     * @returns {*} Returns true if the stored data has been created
     * @private
     */
    var _checkStorage = function (name, options) {
        var temp = tag.storage[_get_storage_method](name);
        if (temp !== null) {
            return (typeof temp === 'object' && !(temp instanceof Array));
        } else {
            tag.storage[_set_storage_method](name, {}, options);
            return true;
        }
    };

    /**
     * Checks if a persistent campaign should be add to the next (page's) hit and do it if necessary
     * @memberof ATInternet.Tracker.Plugins.Campaigns#
     * @function
     * @private
     */
    var _setHitPersistentCampaign = function () {
        if (!_isRedirection && _in_atreman_camp) {
            _setContext('xtor', _in_atreman_camp);
            var currentDate = (new Date()).getTime() / (1000 * 3600);
            var temp = Math.floor(currentDate - _in_atreman_date);
            _setContext('roinbh', (temp >= 0 ? temp : 0));
        }
    };

    /**
     * Transmit campaigns during HTML/Javascript redirection if necessary (config => 'redirect: true')
     * @memberof ATInternet.Tracker.Plugins.Campaigns#
     * @function
     * @private
     */
    var _setRedirectionCampaign = function () {
        var campaign = _in_tag_forcedCampaign || _in_atredir_camp || _in_url_xtor;
        if (_isRedirection && campaign && _checkStorage('atredir', {
            path: '/',
            end: tag.getConfig('redirectionLifetime')
        })) {
            tag.storage[_set_storage_method](
                ['atredir', 'camp'],
                campaign
            );
            var gopc = false;
            var gopc_err = false;
            if (!_in_tag_forcedCampaign) {
                if (_in_atredir_camp) {
                    gopc = _in_atredir_gopc;
                    gopc_err = _in_atredir_gopc_err;
                } else {
                    gopc = _isGopc;
                    gopc_err = _isGopcErr;
                }
            }
            tag.storage[_set_storage_method](
                ['atredir', 'gopc'],
                gopc
            );
            tag.storage[_set_storage_method](
                ['atredir', 'gopc_err'],
                gopc_err
            );
        }
    };

    /**
     * Store the campaign that should become the persistent campaign and add it to the history if necessary
     * @memberof ATInternet.Tracker.Plugins.Campaigns#
     * @function
     * @private
     */
    var _setAtreman = function () {
        if (!_isRedirection) {
            var xto = null;
            if (_in_atredir_camp) {
                xto = _in_tag_forcedCampaign || _in_atredir_camp;
            } else {
                xto = _in_tag_forcedCampaign || _in_url_xtor || xto;
            }
            if (xto && !(
                (!_in_tag_forcedCampaign && !_in_atredir_camp && _isGopc && _isGopcErr) ||
                (!_in_tag_forcedCampaign && _in_atredir_camp && _in_atredir_gopc && _in_atredir_gopc_err)
            )) {
                if ((!_in_atsession_histo_camp || (_in_atsession_histo_camp instanceof Array && _in_atsession_histo_camp.indexOf(xto) < 0)) && _checkStorage('atsession', {
                    path: '/',
                    session: tag.getConfig('visitLifetime') * 60
                })) {
                    tag.storage[_set_storage_method](
                        ['atsession', 'histo_camp'],
                        (_in_atsession_histo_camp && _in_atsession_histo_camp.push(xto) ? _in_atsession_histo_camp : [xto])
                    );
                }
                if ((!_in_atreman_camp || confCampaigns.lastPersistence) && _checkStorage('atreman', {
                    path: '/',
                    session: (confCampaigns.lifetime * 24 * 60 * 60)
                })) {
                    tag.storage[_set_storage_method](
                        ['atreman', 'camp'],
                        xto
                    );
                    tag.storage[_set_storage_method](
                        ['atreman', 'date'],
                        (new Date().getTime() / (3600 * 1000))
                    );
                }
            }
        }
    };

    /**
     * Add a new campaign in the next hit (checking which campaign should be used for that -> xtor_url xtoforce atredir_camp)
     * @memberof ATInternet.Tracker.Plugins.Campaigns#
     * @function
     * @private
     */
    var _setXto = function () {
        if (!_isRedirection) {
            var xto = null;
            if (_in_atredir_camp) {
                if (_in_atredir_gopc) {
                    xto = _in_tag_forcedCampaign || xto;
                } else {
                    xto = _in_tag_forcedCampaign || _in_atredir_camp;
                }
            } else if (_isGopc) {
                xto = _in_tag_forcedCampaign;
            } else {
                xto = _in_tag_forcedCampaign || _in_url_xtor || xto;
            }
            if (_in_atsession_histo_camp && _in_atsession_histo_camp instanceof Array && _in_atsession_histo_camp.indexOf(xto) > -1) {
                xto = null;
            }
            if (xto) {
                _setContext('xto', xto);
            }
        }
    };

    /**
     * Checks if there was an error during a GOPC and add the concerned campaign to the next hit if it's the case
     * @memberof ATInternet.Tracker.Plugins.Campaigns#
     * @function
     * @private
     */
    var _setPgt = function () {
        if (!_isRedirection && !_in_tag_forcedCampaign) {
            var pgt;
            if (_in_atredir_camp) {
                if (_in_atredir_gopc_err) {
                    pgt = _in_atredir_camp;
                }
            } else if (_isGopcErr) {
                pgt = _in_url_xtor;
            }
            if (pgt) {
                _setContext('pgt', pgt);
            }
        }
    };

    /**
     * Launch each task to do when automatic processing is triggered
     * @memberof ATInternet.Tracker.Plugins.Campaigns#
     * @function
     * @private
     */
    var _launchProcess = function () {
        _defineUniquePersistence();
        _retrieveInputValues();
        _processContextValues();
        _setRedirectionCampaign();
        _setHitPersistentCampaign();
        _setXto();
        _setPgt();
        _setAtreman();
    };

    /**
     * Launch campaigns automatic processing
     * @memberof ATInternet.Tracker.Plugins.Campaigns#
     * @function
     * @private
     */
    var _run = function () {
        _launchProcess();
        tag.emit('Campaigns:process:done', {lvl: 'INFO'});
    };

    /**
     * Init method, check dependencies and launch the campaigns plugin when all dependencies are present
     * @memberof ATInternet.Tracker.Plugins.Campaigns#
     * @function
     * @private
     */
    var _init = function () {
        var dependencies = ['Storage', 'Utils'];
        tag.plugins.waitForDependencies(dependencies, function () {
            _run();
        });
    };

    _init();

    // For unit tests on private elements !!!
    /* @if test */
    var self = this;
    self._defineUniquePersistence = _defineUniquePersistence;
    self.Campaigns = Campaigns;
    self._setContext = _setContext;
    self._getParametersFromQuery = _getParametersFromQuery;
    self._retrieveInputValues = _retrieveInputValues;
    self._processContextValues = _processContextValues;
    self._checkStorage = _checkStorage;
    self._setHitPersistentCampaign = _setHitPersistentCampaign;
    self._setRedirectionCampaign = _setRedirectionCampaign;
    self._setAtreman = _setAtreman;
    self._setXto = _setXto;
    self._setPgt = _setPgt;
    self._launchProcess = _launchProcess;
    self._run = _run;
    self._init = _init;
    self._VISIT_LIFETIME = tag.getConfig('visitLifetime');
    self._CAMPAIGNS_LIFETIME = confCampaigns.lifetime;
    self._CAMPAIGNS_LAST_PERSISTENCE = confCampaigns.lastPersistence;
    self.getThemAll = function () {
        self.confCampaigns = confCampaigns;
        self._set_storage_method = _set_storage_method;
        self._get_storage_method = _get_storage_method;
        self._in_atredir_gopc = _in_atredir_gopc;
        self._in_atredir_gopc_err = _in_atredir_gopc_err;
        self._in_atredir_camp = _in_atredir_camp;
        self._in_atsession_histo_camp = _in_atsession_histo_camp;
        self._in_atreman_camp = _in_atreman_camp;
        self._in_atreman_date = _in_atreman_date;
        self._in_url_xtor = _in_url_xtor;
        self._in_url_xtdt = _in_url_xtdt;
        self._in_url_xts = _in_url_xts;
        self._in_tag_forcedCampaign = _in_tag_forcedCampaign;
        self._isRedirection = _isRedirection;
        self._isGopc = _isGopc;
        self._isGopcErr = _isGopcErr;
    };
    self.setInternalVar = function (name, val) {
        if (name === '_in_atredir_gopc') _in_atredir_gopc = val;
        else if (name === '_in_atredir_gopc_err') _in_atredir_gopc_err = val;
        else if (name === '_in_atredir_camp') _in_atredir_camp = val;
        else if (name === '_in_atsession_histo_camp') _in_atsession_histo_camp = val;
        else if (name === '_in_atreman_camp') _in_atreman_camp = val;
        else if (name === '_in_url_xtor') _in_url_xtor = val;
        else if (name === '_in_url_xtdt') _in_url_xtdt = val;
        else if (name === '_in_tag_forcedCampaign') _in_tag_forcedCampaign = val;
        else if (name === '_isGopc') _isGopc = val;
        else if (name === '_isGopcErr') _isGopcErr = val;
    };
    /* @endif */
};
ATInternet.Tracker.addPlugin('Campaigns');