/*jslint node: true */
/*jslint browser: true*/
/*jslint nomen: true*/
/*global BaseController, angular*/

'use strict';

/**
 * environment Directive
 *
 * Use of Class.js
 *
 */
var environmentSelectionDirective = BaseController.extend({
    /**
     * @override
     */

    selectClassOne: null,
    operator: null,
    selectClassTwo: null,
    init: function ($scope, $elm, $attrs, $filter, $modal, $timeout, naviTreeService, environmentService) {
        var self = this;
        this._element = $elm;
        this._attrs   = $attrs;
        this.filter   = $filter;
        this.$modal   = $modal;
        this.$timeout   = $timeout;
        this._naviTreeService    = naviTreeService;
        this._environmentService = environmentService;

        this._super($scope);

        this.$scope.totalHostList = [];
        this.$scope.treeProfiles  = [];

        this.$scope.hostContexts  = {};

        this._naviTreeService.getTreeProfiles().then(
            function (result) {
                self.$scope.treeProfiles = result.data;
            },
            function (error) {
                self.$scope.treeProfiles = [];
            }
        );
    },
    /**
     * @override
     */
    defineListeners: function () {
        var self = this, $scope = self.$scope;

        // watch the context changes in free context form
        $scope.$watch('context', function (val) {
            if (!val) {
                return;
            }

            self.$scope.nodeLevels = []; // reset nodes
            self.$scope.selectedNodeLevel = [];
            self.$scope.selectedProfile = null;

            self.$scope.$emit('environmentProfileChanged_Event', self.$scope.selectedProfile);
            self.$scope.$emit('environmentNodeChanged_Event',    self.$scope.selectedNodeLevel);

            var nodes = [];

            angular.forEach($scope.context, function (value, key) {
                nodes.push({
                    'classRegex': value,
                    'label': value
                });
            });

            self._updateClassEvaluation(nodes);
            self._emitManualClass_selection();
        });

        $scope.$on('clearing', function() {
            self.$scope.addAllHostClass();
        });

        $scope.$watch('state', function (val) {
            self._loadProfilesAndSetSelected(val);
        });
    },

    _loadProfilesAndSetSelected: function (val) {
        var self = this;
        if (val && !angular.equals({}, val)) {
                if (val.profileId && val.profileId !== '') {
                    self._environmentService.getVIEWVariables(val.profileId, val.hostContextsPath).then(
                        function (result) {
                            //FIXME: set timeout to make sure that changes would take place
                            self.$timeout(function () {
                                self.$scope.nodeLevels        = result.nodeLevels;
                                self.$scope.selectedNode      = result.selectedNode;
                                self.$scope.selectedNodeLevel = result.selectedNodeLevel;
                                self.$scope.selectedProfile   = result.selectedProfile;
                                self.$scope.treeNodes         = result.treeNodes;
                                self.$scope.treeProfiles      = result.treeProfiles;

                                var nodes = [];
                                angular.forEach(self.$scope.selectedNodeLevel, function (value, key) {
                                    nodes.push({
                                        'label':value.label,
                                        'classRegex': value.classRegex
                                    });
                                });
                                self._updateClassEvaluation(nodes);
                            });

                        },
                        function (error) {
                             // TODO: - alert if we not able to find profile;
                             // alert for profile added in environment service
                        }
                    );
                } else {  //manual
                    if (val.hostContexts) {
                        var data = val.hostContexts;
                        self.$scope.hostContexts.name = data.name || '';
                        self.$scope.hostContexts.includes = data.includes || '';
                    }
                }
            } else {
                self.$scope.addAllHostClass();
            }
    },

    defineScope: function () {
        var self = this;
        this.$scope.selectedProfile = {};
        this.$scope.treeNodes       = [];
        this.$scope.nodeLevels      = [];
        this.$scope.selectedNodeLevel = [];
        this.$scope.selectedNode      = {};
        this.$scope.hostFilterSet  = false;
        this.$scope.showHosts      = false;
        this.$scope.showHostButton = false;


        this.$scope.updateTreeProfile  = this.updateTreeProfile.bind(this);
        this.$scope.addNodeLevel       = this.addNodeLevel.bind(this);
        this.$scope.showHost           = this.showHost.bind(this);
        this.$scope.addAllHostClass    = this.addAllHostClass.bind(this);
        this.$scope.clearContextFields = this.clearContextFields.bind(this);

        this.$scope.applyFilter        = this.applyFilter.bind(this);

        this.$scope.showMeFilter       = this.showMeFilter.bind(this);

        this.$scope.emitClearFilters = this.emitClearFilters.bind(this);
    },

    emitClearFilters: function () {
        // sends message to clear attr filters
        this.$scope.$emit('clearFilters_EVENT');
    },

    clearContextFields: function () {
        this.$scope.nodeLevels        = []; // reset nodes
        this.$scope.selectedNodeLevel = [];
        this.$scope.context           = null;
        this.$scope.hostContexts             = {};
        this.$scope.hostContexts.name          = null;
        this.$scope.hostContexts.includes      = null;
        this.$scope.selectedProfile   = null;
    },

    updateTreeProfile: function (tree) {
        var self = this;
        this.$scope.selectedProfile = angular.copy(tree);
        this.$scope.showHosts = false;
        this.$scope.$emit('environmentProfileChanged_Event', this.$scope.selectedProfile);
        this._naviTreeService.getTreeNodes(tree).then(
            function (result) {
                self.$scope.treeNodes = result.data;
                self.$scope.nodeLevels = []; // reset nodes
                //self.$scope.selectedNodeLevel = [];
                self.$scope.hostContexts.name = '';
                self.$scope.nodeLevels.push(result.data);
                self.$scope.showHostButton = false;
            },

            function (error) {
                self.$scope.treeNodes = [];
            }
        );
    },

    addNodeLevel: function (node, index) {
        this.$scope.showHosts = false;
        // remove everthing after the index;
        var startIndex = (index == 0) ? 0 : index;
        this.$scope.nodeLevels = this.$scope.nodeLevels.slice(0, startIndex + 1);
        this.$scope.selectedNodeLevel = this.$scope.selectedNodeLevel.slice(0, startIndex + 1);
        this.$scope.selectedNodeLevel[index] = node;
        this.$scope.selectedNode = node;
        this.$scope.context = null;

        this._updateClassEvaluation(this.$scope.selectedNodeLevel);
        if (node.children && node.children.length > 0) {
            this.$scope.nodeLevels.push(node.children);
        }

        this.$scope.$emit('environmentNodeChanged_Event', this.$scope.selectedNodeLevel);
    },

    showHost: function () {
        var self = this;
        this.hostListModalInstance = this.$modal.open({
            templateUrl: 'hostSelectionModal.html',
            backdrop: 'static',
            keyboard: true,
            controller: function($scope, $modalInstance, naviTreeService, $filter, hostContexts) {
                var self = this;
                $scope.totalHostList =   [];
                $scope.originalHostList = [];
                $scope.selectedHosts = {};
                $scope.hostSearch = {};
                $scope.hostSearch.input = '';
                $scope.allchecked = true;
                $scope.showHosts = false;

                $scope.checkAllHosts = function() {

                    if ($scope.allchecked) {
                        $scope.selectedHosts = {};
                        $('.host-selector').attr('checked',false);
                    } else {
                        $scope.setAllSelected();
                        $('.host-selector').attr('checked',true);
                    }
                    $scope.allchecked = !$scope.allchecked;
                };


                $scope.disableButton = function() {
                    //checks if selected host list is empty
                    var empty = angular.equals({},$scope.selectedHosts);
                    return empty;
                };


                $scope.runHostSearch = function (event) {
                    $scope._filterHosts();
                };

                $scope._filterHosts = function (event) {
                    $scope.searchUsedFlag = true;

                    var filteredHosts = [];
                    angular.forEach($scope.originalHostList, function (field, key) {
                        if (field.hostname.indexOf($scope.hostSearch.input) !== -1) {
                            filteredHosts.push(field);
                        }
                    });


                    if ($scope.hostSearch.input !== undefined && $scope.hostSearch.input.length > 0) {
                        $scope.totalHostList = filteredHosts;
                        $scope.selectedHosts = {};
                        $scope.setAllSelected();
                        $scope.disableButton();
                    } else {
                        $scope.totalHostList = $scope.originalHostList;
                    }
                };

                $scope.close = function () {
                    $modalInstance.close('cancel');
                };

                $scope.hostMarkAsSelected = function (host) {
                    var name = host.hostname;
                    var key = host.id;
                    var classKey = key.replace("SHA=", "PK_SHA_");
                    if ($scope.selectedHosts[classKey]) {
                        $scope.allchecked = false;
                        delete $scope.selectedHosts[classKey];
                    } else {
                        $scope.selectedHosts[classKey] = name;
                    }
                    $scope.disableButton();
                };


                $scope.useSelectedHost = function() {
                    $modalInstance.close($scope.selectedHosts);
                };

                 $scope.setAllSelected = function() {
                    //populate selectedHost list so all hosts in group are checked by default
                    angular.forEach($scope.totalHostList, function(value,key){
                        $scope.hostMarkAsSelected(value);
                    });
                };


                var getNodeHostSuccess = function (result) {
                    $scope.totalHostList = result.data;
                    $scope.originalHostList = angular.copy($scope.totalHostList);
                    $scope.setAllSelected();
                    $scope.showHosts = true;
                };

                var getNodeHostfailure = function (error) {
                        $scope.hostListError = error.data;
                        $scope.totalHostList = [];
                        $scope.selectedHosts = {};
                        $scope.showHosts = true;
                    };

                hostContexts.includes = hostContexts.includes || [];
                naviTreeService.getNodeHosts(hostContexts.includes).then(getNodeHostSuccess, getNodeHostfailure);
            },
            resolve: {
                naviTreeService: function () {
                    return self._naviTreeService;
                },
                $filter: function () {
                    return self.filter;
                },
                hostContexts: function () {
                    return self.$scope.hostContexts;
                }
            }
        });


        this.hostListModalInstance.result.then(function (selectedHosts) {
            var nodes = [];
            var regex = Object.keys(selectedHosts).join('|');
            var names = [];
            for (var key in selectedHosts) {
                var val = selectedHosts[key];
                names.push(val);
            }
            var envName = names.join(', ');
            nodes.push({
                'classRegex': regex,
                'label':envName
            });
            self._updateClassEvaluation(nodes);
        });
    },

    addAllHostClass: function () {
        this.clearContextFields();
        this.$scope.hostContexts.name = '';
        this.$scope.hostContexts.includes = [''];
        this.$scope.selectedProfile = {
            name: 'All hosts'
        };

        this.$scope.$emit('environmentProfileChanged_Event', this.$scope.selectedProfile);
        this.$scope.showHostButton = true;
    },

    _updateClassEvaluation: function (nodes) {
        var self = this, regex = [];
        var label = [];

        angular.forEach(nodes, function(val) {
            regex.push(val.classRegex.replace(/[-.]/g,"_"));
            label.push(val.label);
        });

        var environmentLabel =  label.join(' and ');

        this.$scope.hostContexts.name = environmentLabel;
        this.$scope.hostContexts.includes = regex;

        self._emitManualClass_selection();

    },
    showMeFilter: function () {
        var self = this, $scope = self.$scope;
        $scope.showFilter = ($scope.showFilter === true ? false : true);
    },

    applyFilter: function() {
        var self = this, objToEmit = {};

        objToEmit.hostcontexts = self.$scope.hostContexts || {};
        objToEmit.hostcontextsprofileid = (this.$scope.selectedProfile && this.$scope.selectedProfile.id ? this.$scope.selectedProfile.id : '');

        if (this.$scope.selectedNodeLevel.length)
        {
            var nodePath = [];
            angular.forEach(this.$scope.selectedNodeLevel, function(node, id) {
                nodePath.push(node.label);
            });
            objToEmit.hostcontextspath = JSON.stringify(nodePath);
        }
        else {
            objToEmit.hostcontextspath = '';
        }


        self.$scope.$emit('hostContextApply_Event', objToEmit);
     },

    /* emit event and send env object with manually entered classes (or selected from hostpopup)  */
    _emitManualClass_selection: function () {
        var self = this, objToEmit = {};
        objToEmit.name = self.$scope.hostContexts.name;
        objToEmit.includes = self.$scope.hostContexts.includes;
        self.$scope.$emit('environmentHostContextChange_Event', objToEmit);
    }
});