Source: managers/search.js

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

    var device = RuntimeContext.getDevice(),
        storage = device.getStorage(StorageProvider.STORAGE_TYPE_PERSISTENT, 'kpn-search'),
        instance,
        SearchManager,
        lastsearcheditem = 'last-searched-items',
        api = ApiManager.getKPNAPI();

    SearchManager = Class.extend({

        /**
         * Returns last searched Items.
         *
         * @returns {Array} - The 10 last searched items.
         */
        getLastSearchedItems: function () {
            return storage.getItem(lastsearcheditem);
        },

        /**
         * Sets the last searched items stringify array.
         *
         * @param {string} searchedItems - The last searched item.
         */
        setLastSearchedItems: function (searchedItems) {
            storage.setItem(lastsearcheditem, searchedItems);
        },

        /**
         * Updating last searched items.
         *
         * @param {string} newValue - New walue passed onSelect.
         */
        addLastSearchedItem: function (newValue) {
            var searchedItems = this.getLastSearchedItems(),
                searchedItemsArray,
                newItems,
                arrayLength;

            if (searchedItems) {
                searchedItemsArray = searchedItems.split('~');
                arrayLength = searchedItemsArray.length;
                if (arrayLength < 10) {

                    // Add new query.
                    if (searchedItemsArray.indexOf(newValue) === -1) {
                        searchedItemsArray.push(newValue);
                    } else if (searchedItemsArray.indexOf(newValue) >= 0) {
                        searchedItemsArray.splice(searchedItemsArray.indexOf(newValue), 1);
                        searchedItemsArray.push(newValue);
                    } else {
                        searchedItemsArray.push(newValue);
                    }

                    newItems = searchedItemsArray.join('~');
                    this.setLastSearchedItems(newItems);
                } else if (arrayLength >= 10) {

                    // Add new query.
                    if (searchedItemsArray.indexOf(newValue) === -1) {
                        searchedItemsArray.push(newValue);
                    } else if (searchedItemsArray.indexOf(newValue) >= 0) {
                        searchedItemsArray.splice(searchedItemsArray.indexOf(newValue), 1);
                        searchedItemsArray.push(newValue);
                    } else {
                        searchedItemsArray.push(newValue);
                    }
                    searchedItemsArray = searchedItemsArray.slice(-10);
                    newItems = searchedItemsArray.join('~');
                    this.setLastSearchedItems(newItems);
                }
            } else {
                this.setLastSearchedItems(newValue);
            }
        },

        /**
         * Clears the last searched items.
         */
        clearLastSearchedItems: function () {
            storage.removeItem(lastsearcheditem);
        },

        /**
         * Send search request to the backend.
         *
         * @param {string} query - Phrase to look for ion the database.
         * @param {number} startTime - Start time to filter.
         * @param {number} endTime - End time to filter.
         * @param {string} genre - Genre.
         * @returns {Promise} Returns Promise, that resolves to array of SearchResult objects.
         */
        search: function (query, startTime, endTime, genre) {
            var params = {
                params: {
                    query: query,
                    startTime: startTime,
                    endTime: endTime,
                    genre: genre
                },
                withCredentials: true
            }, searchPromises = [];

            searchPromises.push(api.read('search', params));
            searchPromises.push(api.read('searchlive', params));

            return Promise.all(searchPromises).then(function (results) {
                return results[1].concat(results[0]);
            });
        },

        /**
         * Searches api for content of genre.
         *
         * @param {string} genre - Genre.
         * @param {number} startTime - Start time to filter.
         * @param {number} endTime - End time to filter.
         * @param {boolean} [filterProgramType] - Should genre filtering happen in Program type.
         * @returns {Promise} - Returns Promise that resolves with search data.
         */
        searchByGenre: function (genre, startTime, endTime, filterProgramType) {
            var params = {
                params: {
                    startTime: startTime,
                    endTime: endTime,
                    genre: genre,
                    formatByChannel: true,
                    filterProgramType: filterProgramType ? filterProgramType : false,
                    query: ''
                },
                withCredentials: true
            };

            return api.read('search', params);
        },

        /**
         * Requests placeholder content.
         *
         * @returns {Promise} - Returns Promise that resolves with placeholders data.
         */
        searchPlaceholders: function () {
            var trendingParams = {
                    params: {
                        maxResults: 10
                    },
                    withCredentials: true
                },
                searchParams = {
                    params: {
                        query: '',
                        orderBy: 'activationDate',
                        sortOrder: 'desc',
                        from: 0,
                        to: 10,
                        dfilter_packages: 'subscription',
                        filter_quality: 'hd',
                        filter_contentType: 'VOD,GROUP_OF_BUNDLES',
                        filter_contentSubtype: 'SERIES,VOD',
                        filter_fuzzy: true,
                        _searchContentType: 'vod'
                    },
                    withCredentials: true
                },
                searchPromises = [];

            searchPromises.push(api.read('trending', trendingParams));
            searchPromises.push(api.read('searchall', searchParams));

            return Promise
                .all(searchPromises)
                .then(function (results) {
                    return [
                        {data: results[0]},
                        {data: results[1]}
                    ];
                });
        },

        /**
         * Executes search request to the backend.
         *
         * @param {string} searchData - Contains the search params to be requested.
         * @returns {Promise} Returns Promise, that resolves to array of SearchResult objects.
         */
        searchContent: function (searchData) {
            var todayAndLaterParams = {
                    params: {
                        query: searchData.query,
                        dfilter_channels: 'subscription',
                        filter_airingStartTime: 'now',
                        filter_fuzzy: true,
                        filter_isTvPremiere: true,
                        filter_channelType: 'EXTENDED',
                        sortOrder: 'asc',
                        orderBy: 'airingStartTime',
                        from: 0,
                        to: 19,
                        _searchContentType: 'program'
                    },
                    withCredentials: true
                },
                catchupParams = {
                    params: {
                        query: searchData.query,
                        dfilter_channels: 'subscription',
                        filter_startTime: searchData.catchup.startTime,
                        filter_endTime: searchData.catchup.endTime,
                        filter_isCatchup: true,
                        filter_fuzzy: true,
                        filter_isTvPremiere: true,
                        filter_channelType: 'EXTENDED',
                        sortOrder: 'desc',
                        orderBy: 'airingStartTime',
                        from: 0,
                        to: 19,
                        _searchContentType: 'program'
                    },
                    withCredentials: true
                },
                searchParams = {
                    params: {
                        query: searchData.query,
                        dfilter_packages: 'subscription',
                        orderBy: 'title',
                        sortOrder: 'asc',
                        filter_quality: 'hd',
                        filter_contentType: 'VOD,GROUP_OF_BUNDLES',
                        filter_contentSubtype: 'SERIES,VOD',
                        filter_fuzzy: true,
                        from: 0,
                        to: 19,
                        _searchContentType: 'vod'
                    },
                    withCredentials: true
                },
                searchPromises = [];

            searchPromises.push(api.read('searchall', todayAndLaterParams));
            searchPromises.push(api.read('searchall', catchupParams));
            searchPromises.push(api.read('searchall', searchParams));

            return Promise
                .all(searchPromises)
                .then(function (results) {
                    return [
                        {data: results[0]},
                        {data: results[1]},
                        {data: results[2]}
                    ];
                });
        }
    });

    return {

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

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

            return instance;
        }
    };
});