Source: managers/halo.js

define('application/managers/halo', [
    'antie/runtimecontext',
    'antie/class',
    'rofl/lib/utils',
    'application/managers/api',
    'rofl/lib/promise'
], function (
    RuntimeContext,
    Class,
    Utils,
    ApiManager,
    Promise
) {
    'use strict';

    var instance,
        HaloManager,
        api,
        MODELS = {
            CONFIG: 'configuration',
            OAUTH: 'authentication/oauth',
            EDITORIAL: 'editorial',
            SERVICE_MESSAGE: 'servicemessage'
        },
        GRANT_TYPES = {
           CLIENT_CREDENTIALS: 'client_credentials'
        },
        SERVICES = {
            GET_TOKEN: 'GET_TOKEN'
        };

    HaloManager = Class.extend({

        init: function init () {
            api = ApiManager.getHaloAPI();
        },

        /**
         * Sets the api configuration.
         *
         * @param {Object} apiConfig - The API configuration parameters.
         * @private
         */
        _setConfig: function (apiConfig) {
            this._apiConfig = apiConfig;
            this._credentials = apiConfig.CREDENTIALS;
        },

        /**
         * Sets the requested token authorization data.
         * Authorization token to be used for API requests.
         *
         * @param {Object} data - Requested authorization token data.
         * @param {string} data.access_token - Authorization token.
         * @param {string} data.refresh_token - Token refresh.
         * @param {string} data.expires_in - Token expiration time(ms).
         * @param {string} data.scope - Token scope.
         * @param {string} data.token_type - Token type.
         * @private
         */
        _setTokenData: function (data) {
            data = data || {};

            this._accessToken = data.access_token;
            this._tokenType = data.token_type;
        },

        /**
         * Requests & sets Halo configuration credentials and requests oAuth token with credentials.
         *
         * @returns {PromiseLike<T>} - Promise.
         */
        getConfig: function () {
            return api.read(MODELS.CONFIG)
                .then(Utils.bind(this._setConfig, this))
                .then(Utils.bind(this.getToken, this));
        },

        /**
         * Request & sets the authorization token data.
         *
         * @returns {MODELS.OAUTH} - Returns resolved endpoint data.
         */
        getToken: function () {
            var credentials = this._credentials,
                params = {
                withCredentials: false,
                asQuery: true,
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                },
                params: {
                    service: SERVICES.GET_TOKEN
                },
                data: {
                    grant_type: GRANT_TYPES.CLIENT_CREDENTIALS,
                    client_id: credentials.clientId,
                    client_secret: credentials.clientSecret
                }
            };

            return api.create(MODELS.OAUTH, params)
                .then(Utils.bind(this._setTokenData, this))
                ['catch'](Utils.bind(this._setTokenData, this));
        },

        /**
         * Returns the Halo module.
         *
         * @param {string} module - The api module to be used.
         * @param {string|Array} moduleName - The name of the module or modules.
         * @param {boolean} [byIds] - True if the modules should be loaded by id.
         *
         * @returns {Promise} - Promise resolving witht he module data.
         */
        getModule: function (module, moduleName, byIds) {
            var promise = Promise.resolve(),
                self = this;

            if (!this._tokenType || !this._accessToken) {
                promise = this.getToken();
            }

            return promise.then(function () {
                var data = {
                    segmentTags: [{
                        'name': 'Brand',
                        'tagType': '000000000000000000000002',
                        'value': 'KPN'
                    }],
                    include: ['all']
                };

                if (moduleName instanceof Array) {

                    if (byIds) {
                        data.moduleIds = moduleName;
                    } else {
                        data.moduleNames = moduleName;
                    }
                } else {
                    data.moduleName = moduleName;
                }

                return api.create(module, {
                    headers: {
                        Authorization: self._tokenType + ' ' + self._accessToken
                    },
                    data: data
                });
            });
        },

        /**
         * Returns the sports screen data.
         *
         * @returns {Object} - The sports screen data.
         */
        getSportsScreenData: function () {
            return this.getModule(MODELS.EDITORIAL, 'SportsScreen');
        },

        /**
         * Retrieves the service message.
         *
         * @returns {Promise} - The service message promise.
         */
        getServiceMessage: function () {
            var self = this,
                timeToUpdate = 15 * 60 * 1000,
                now = new Date();

            if (!this._serviceMessage || (now - this._timeSinceLastServiceUpdate) >= timeToUpdate) {
                return this.getModule(MODELS.SERVICE_MESSAGE, 'Service Message')
                    .then(function (result) {
                        self._serviceMessage = result;
                        self._timeSinceLastServiceUpdate = new Date();

                        return result.isEnabled();
                    });
            }

            return Promise.resolve(this._serviceMessage.isEnabled());

        },

        /**
         * Returns the service message title if it has been retrieved.
         *
         * @returns {string} - The service message title.
         */
        getServiceTitle: function () {
            return this._serviceMessage && this._serviceMessage.getServiceTitle();
        },

        /**
         * Returns the service message text if it has been retrieved.
         *
         * @returns {string} - The service message text.
         */
        getServiceText: function () {
            return this._serviceMessage && this._serviceMessage.getServiceText();
        }
    });

    return {

        /**
         * Returns the instance.
         *
         * @returns {Object} - The instance.
         */
        getInstance: function () {

            if (!instance) {
                instance = new HaloManager();
            }

            return instance;
        }
    };
});