'use strict';
/*common functions */


angular.
    module('inventoryHelpers', []).
    factory('inventoryHelper', ['$q', 'inventoryService', 'notificationService', 'inventoryDataService', '$rootScope',
                        function($q,   inventoryService,   notificationService, inventoryDataService, $rootScope) {
    var helper = {};

    var inventoryVariables = {};


    /* Initial object */
    inventoryVariables.CFE_mapping = {};
    inventoryVariables.InventoryItems = {};
    inventoryVariables.InventoryItems.groups = {};
    inventoryVariables.InventoryItems.filters = {};

    inventoryVariables.InventoryItems.groups.hardwareGroup    = {};
    inventoryVariables.InventoryItems.groups.softwareGroup    = {};
    inventoryVariables.InventoryItems.groups.networkGroup     = {};
    inventoryVariables.InventoryItems.groups.securityGroup    = {};
    inventoryVariables.InventoryItems.groups.noCategoryGroup  = {};
    inventoryVariables.InventoryItems.groups.noGroupGroup     = {};

    inventoryVariables.InventoryItems.filters.hardwareFilter   = {};
    inventoryVariables.InventoryItems.filters.softwareFilter   = {};
    inventoryVariables.InventoryItems.filters.networkFilter    = {};
    inventoryVariables.InventoryItems.filters.securityFilter   = {};
    inventoryVariables.InventoryItems.filters.noCategoryFilter = {};
    inventoryVariables.InventoryItems.filters.noGroupFilter    = {};


    /**
     * Get inventory variables from DB
     *
     * @returns {@exp;defered@pro;promise}
     */
    helper.getInventoryVariables = function(addFields, removeFields, addFilters) {
        var self = this, defered = $q.defer();

        inventoryDataService.getVariables().then(
            function(result) {
                $rootScope.$emit('inv_variables_loaded', result);
                inventoryVariables.CFE_mapping = result;
                self._setGroupsForColumnsAndFilters_updateCFE_mapping(addFields, removeFields, addFilters);

                defered.resolve(inventoryVariables);
            },
            function(error) {
                error.data[0].text = error.data[0].text || 'Error encountered. Please view the logs for more detailed information.';
                notificationService.setNotification('error', error.data);
                defered.reject(error);
            }
        );

        return defered.promise;
    };


    /**
     * Save variable dictionary to DB
     *
     * @returns {@exp;defered@pro;promise}
     */
    helper.updateVariablesDictionary = function(data) {
        var defered = $q.defer();

        inventoryService.updateVariablesDictionary(data).then(
                function(result) {
                    defered.resolve(result);
                },
                function(error) {
                    error.data[0].text = error.data[0].text || 'Error encountered. Please view the logs for more detailed information.';
                    notificationService.setNotification('error', error.data);
                    defered.reject(error);
                }
        );

        return defered.promise;
    };




    /**
     * Construct inventory object, append additional fields from DCA
     *
     * @returns {inventoryVariables}
     */
    helper._setGroupsForColumnsAndFilters_updateCFE_mapping = function(addFields, removeFields, addFilters) {
        var self = this;
        // just for convenience when build SQL string add source_table to the fields
        // we need source because some items, like software version has different source
        angular.forEach(inventoryVariables.CFE_mapping, function(field, index) {
            field.source_table = "inventory";
        });


        // add hostname to CFE_mapping
        if(!angular.equals({}, addFields)) {
            angular.forEach(addFields, function(field, index) {
                if (!inventoryVariables.CFE_mapping[field.attribute_name])
                {
                    inventoryVariables.CFE_mapping[field.attribute_name] = {};
                    inventoryVariables.CFE_mapping[field.attribute_name] = field;
                }
            });
        }

        // Remove fields which shouldn't exist in CFE_mapping
        if (removeFields) {
            angular.forEach(removeFields, function(field, index) {
                    if (inventoryVariables.CFE_mapping[field]) {
                        delete inventoryVariables.CFE_mapping[field];
                    }
            });
        }

        inventoryVariables.InventoryItems.groups.hardwareGroup   = self.getCategoryItems('Hardware');
        inventoryVariables.InventoryItems.groups.softwareGroup   = self.getCategoryItems('Software');
        inventoryVariables.InventoryItems.groups.networkGroup    = self.getCategoryItems('Network');
        inventoryVariables.InventoryItems.groups.securityGroup   = self.getCategoryItems('Security');
        inventoryVariables.InventoryItems.groups.noCategoryGroup = self.getNoCategoryItems();
        inventoryVariables.InventoryItems.groups.noGroupGroup    = self.getNoGroupItems();

        //combine to get a groupable list for dropdown check boxes
        inventoryVariables.InventoryItems.grouped = inventoryVariables.InventoryItems.groups.hardwareGroup.concat(inventoryVariables.InventoryItems.groups.softwareGroup,inventoryVariables.InventoryItems.groups.networkGroup,inventoryVariables.InventoryItems.groups.securityGroup,inventoryVariables.InventoryItems.groups.noCategoryGroup,inventoryVariables.InventoryItems.groups.noGroupGroup);

        // copy
        inventoryVariables.InventoryItems.filters.hardwareFilter   = inventoryVariables.InventoryItems.groups.hardwareGroup.slice(0);
        inventoryVariables.InventoryItems.filters.softwareFilter   = inventoryVariables.InventoryItems.groups.softwareGroup.slice(0);
        inventoryVariables.InventoryItems.filters.networkFilter    = inventoryVariables.InventoryItems.groups.networkGroup.slice(0);
        inventoryVariables.InventoryItems.filters.securityFilter   = inventoryVariables.InventoryItems.groups.securityGroup.slice(0);
        inventoryVariables.InventoryItems.filters.noCategoryFilter = inventoryVariables.InventoryItems.groups.noCategoryGroup.slice(0);
        inventoryVariables.InventoryItems.filters.noGroupFilter    = inventoryVariables.InventoryItems.groups.noGroupGroup.slice(0);

        // add items to filters

        if(!angular.equals({}, addFilters)) {
            angular.forEach(addFilters, function(filterType, filterId) {
                //check if filter type exists
                if (inventoryVariables.InventoryItems.filters[filterId]) {
                    angular.forEach(filterType, function(field, index) {
                        inventoryVariables.InventoryItems.filters[filterId].push(field);
                    });
                }
            });
        }
        return inventoryVariables;
    };

    /**
     * Return items by category
     *
     * @param category {string}
     *
     * @returns {Array}
     */
    helper.getCategoryItems = function (category) {
        var self = this, result = [];

        var thisCategory = category.toLowerCase();
        // get all items related to this category
        angular.forEach(inventoryVariables.CFE_mapping, function (field, id) {
            if (field.category && field.category.toLowerCase() === thisCategory) {
                field.id = id; // add id as property
                result.push(field);
            }
        });
        return result;
    };

    /**
     * Return items where category is not specified
     *
     * @returns {Array}
     */
    helper.getNoCategoryItems = function() {
        var self = this, result = [];

        angular.forEach(inventoryVariables.CFE_mapping, function (field, id) {
            // we must add check for user defined because if we save variable without category it will have category = user defined
            if ( (field.category === undefined || field.category==='User defined') && field.attribute_name !== undefined && field.attribute_name.indexOf('attribute_name=') !== -1) {
                field.id = id; // add id as property
                field.category = 'User defined';
                result.push(field);
            }
        });
        return result;
    };

    /**
     * Return items where attribute name is not specified
     *
     * @returns {Array}
     */
    helper.getNoGroupItems = function() {
        var self = this, result = [];
        angular.forEach(inventoryVariables.CFE_mapping, function (field, id) {
//check for host name - hack, we can not use atribute_name, because we remove it, see DCA_addons
            if (field.attribute_name && field.attribute_name.indexOf('attribute_name=') === -1 && field.attribute_name !== 'Host name' ) {
                field.id = id; // add id as property
                field.category = 'Missing attribute_name';
                result.push(field);
            }
        });
        return result;
    };

    return helper;
}]);


