//(C) Copyright 2020 Hewlett-Packard Enterprise Company, L.P.
define(
        [ 'hp/core/Router', 'fs/presenter/users/UsersPresenter',
                'fs/presenter/settings/AuthNPresenter', 'hp/core/Localizer',
                'hp/model/Session', 'hp/view/FormStateView',
                'hp/view/DialogView', 'hp/core/Notifications',
                'fs/view/users/UsersViewUtil',
                'lib/jquery.selectBox', 'hp/lib/jquery.hpToggle',
                'lib/jquery.validate' ],
        function(router, usersPresenter, authnPresenter, Localizer, session,
                FormStateView, DialogView, notifications, UsersViewUtil) {
            "use strict";

            var EditDirectoryUserGroupView = (function() {
                var HEADER = '#fs-user-group-edit-header',
                AUTHN_SERVICES_TEXT = '#fs-usersGroup-authn-services-text',
                ROLE_VALIDATOR = '#fs-user-role-validator',
                ROLES_LIST = '#fs-user-roles-list',
                ROLES = ROLES_LIST + ' input[type="checkbox"]',
                ROLE = '#fs-user-role',
                ROLE_OPTION = 'input:radio[name=' + ROLE + ']',
                ROLE_SET = '#fs-user-role-set',
                READ_ONLY_ACCESS = '#fs-user-role-readonly-access',
                FULL_ACCESS = '#fs-user-role-full-access',
                FORM = '#fs-user-group-edit-form',
                OK = '#fs-edit-user-group',
                GROUP = '#user-groups-text',
                SPECIALIZED_RADIO = '#fs-user-role-specialized',
                READONLY_RADIO = '#fs-user-role-readonly',
                FULL_RADIO = '#fs-user-role-full',
                USER_NAME_TEXT = '#fs-settings-authn-user-name-text',
                PASSWORD_TEXT = '#fs-settings-authn-password-text';

               function EditDirectoryUserGroupView() {
                 
                    var roleTemplate = null;
                    var validator;
                    // prevent double click
                    var isSubmitted;
                    var taskName;
                    var numberOfClicks = 0;
                    var formStateView = new FormStateView();
                    /**
                     * @private
                     */
                 function formatNotificationDetails(serverError) {
                    var resolutionList = serverError.recommendedActions;
                    var resolutionMessage = "";
                      $.each(resolutionList, function(index, resolution) {
                             resolutionMessage = resolutionMessage + resolution + " <br> ";
                            });
                        var failureNotificationDetailsObj = {
                            summary : Localizer.getString('fs.users.edit.update'),
                            sourceName : $(GROUP).val(),
                            uri : taskName,
                            changing : false,
                            details : Localizer.getString('fs.users.userGroup.update_error', [$(GROUP).val()]) +
                            '\n' + serverError.message + " " + resolutionMessage +
                            '\n' + serverError.details,
                            status : "error"
                        };
                        return failureNotificationDetailsObj;
                    }
                    /**
                     * @private
                     */
                    function onError(errorInfo) {
                       var details = ''; 
                       var resolutions = ''; 
                       var failureNotificationDetails = ''; 
                       var serverErrorList = errorInfo.nestedErrors; 
                       if(serverErrorList.length !== 0){
                       $.each(serverErrorList, function(index, serverError) { 
                             details = details + serverError.details; 
                             var resolutionList = serverError.recommendedActions; 
                              failureNotificationDetails = formatNotificationDetails(serverError); 
                              $.each(resolutionList, function(index, resolution) { 
                                      resolutions = resolutions + resolution + ' <br> '; 
                              }); 
                        });
                      }else {
                        details = errorInfo.details ; 
                        resolutions = errorInfo.resolution;
                      }
                      if (failureNotificationDetails == ''){
                          failureNotificationDetails = {
	                          summary : Localizer.getString('fs.users.edit.update'),
	                          sourceName : $(GROUP).val(),
	                          uri : taskName,
	                          changing : false,
	                          details : Localizer.getString('fs.users.userGroup.update_error', [$(GROUP).val()]),
	                          status : "error"
                    	  };
                      }
                      formStateView.setMessage({
                            summary : details,
                            status : 'error',
                            details : resolutions
                        });
                      notifications.add(failureNotificationDetails, true);
                      isSubmitted = false;
                    }
                    /**
                     * @private To check the checkbox or uncheck the checkbox of a role
                     * under 'Specialized' radio button if only 1 specialized role is
                     * present in list.
                     */
                    function autoCheckSpecializedRole(boolValue){
                        var theRoles = $(ROLES);
                        if (theRoles.length === 1){
                            theRoles.prop('checked',boolValue).trigger('change');
                        }
                    }

                    /**
                     * @private
                     */
                    function onRoleTypeChange() {
                        if($(SPECIALIZED_RADIO).is(':checked')) {
                            $(READ_ONLY_ACCESS).hide();
                            $(FULL_ACCESS).hide();
                            $(ROLES_LIST).show();
                            autoCheckSpecializedRole(true);
                        } else if ($(READONLY_RADIO).is(':checked')) {
                            $(READONLY_RADIO).attr('value', Localizer.getString('fs.users.common.read_only'));
                            $(READ_ONLY_ACCESS).show();
                            $(FULL_ACCESS).hide();
                            autoCheckSpecializedRole(false);
                            $(ROLES_LIST).hide();
                        } else if($(FULL_RADIO).is(':checked')) {
                            $(FULL_RADIO).attr('value', Localizer.getString('fs.users.common.infrastructure_administrator'));
                            $(READ_ONLY_ACCESS).hide();
                            $(FULL_ACCESS).show();
                            autoCheckSpecializedRole(false);
                            $(ROLES_LIST).hide();
                        }
                    }
                    /**
                     * @private
                     * populate all the roles data from the server
                     */
                    function updateRoles() {
                        var roles = usersPresenter.getRoles();
                        $(ROLES_LIST).empty();
                        $.each(roles, function(index, role) {
                            if (role.roleName !== 'No_Privileges' &&
                                   role.roleName !== Localizer.getString('fs.users.common.infrastructure_administrator') &&
                                   role.roleName !== Localizer.getString('fs.users.common.read_only')){
                                var item = null;
                                    item = roleTemplate.clone();
                                var id = 'fs-user-role-' + index;
                                var label = UsersViewUtil.getLocalizedRoleDisplay(role.roleName);
                                item.attr('id', '');
                                item.show();
                                $('input[type="checkbox"]', item)
                                        .attr('id', id).val(role.roleName)
                                        .attr('name', role.roleName);
                                $('label:eq(1)', item).text(label).attr('for',
                                        id);
                                $(ROLES_LIST).append(item);
                                if (index === 0) {
                                    $(ROLE_VALIDATOR).rules("add", {
                                        GroupToRoleValidation : ROLE_VALIDATOR
                                    });
                                }
                            }
                        });
                        autoCheckSpecializedRole(true);
                        formStateView.reset();
                     }
                    /**
                     * @private
                     */
                    function reset() {
                        $(USER_NAME_TEXT).val("");
                        $(PASSWORD_TEXT).val("");
                        $(ROLES).removeAttr('checked');
                        validator.resetForm();
                        numberOfClicks = 0;
                        isSubmitted = false;
                        updateRoles();
                    }
                    /**
                     * @private
                     */
                    function onUpdateGroup2RoleMappingSuccess() {
                        var grpName = $(GROUP).val();

                        var alertMsg = Localizer.getString(
                                'fs.users.userGroup.update_success',
                                [grpName]);
                        formStateView.setMessage({
                            summary : alertMsg,
                            status : 'ok',
                            changing : false
                        });
                        reset();
                        var grpUpdatedSuccess = {
                            summary : Localizer.getString('fs.users.edit.update'),
                            sourceName : grpName,
                            uri : taskName,
                            changing : false,
                            status : "ok",
                            details : alertMsg
                        };
                        notifications.add(grpUpdatedSuccess, true);
                        router.go('/user/show', 'user show');
                     }
                    function setEditRole(roles){
                     var list = $(SPECIALIZED_RADIO).is(':checked') ? ROLES_LIST : ROLE_SET;
                     $(':checked', list).each(function(index, item) {
                         roles.push($(item).val());
                     });
                    }
                    /**
                     * @private
                     * call this method on click OK to update group to role mapping
                     */
                    function onEditGroupToRoleMappings() {

                         if ($(FORM).valid() && isSubmitted === false ) {
                                numberOfClicks = numberOfClicks + 1 ;
                                isSubmitted = true;
                                var alertMsg = Localizer.getString('fs.users.userGroup.edit_message', [$(GROUP).val()]);
                                formStateView.setMessage({summary:alertMsg, status:'info', changing : true});
                                if(numberOfClicks === 1){
                                    taskName = $(GROUP).val() +'-editGroupToRoleMappingTask-' + (new Date()).getTime();
                                }
                                var groupEditProgress = {
                                    summary : Localizer.getString('fs.users.edit.update'),
                                    sourceName : $(GROUP).val(),
                                    uri : taskName,
                                    changing : true,
                                    status : "info",
                                    details : alertMsg
                                };
                                notifications.add(groupEditProgress, false);
                                var roles = [];
                                setEditRole(roles);
                                var group2rolemappingsConfig = {
                                   "egroup" : $(GROUP).val(),
                                    "loginDomain" : $(AUTHN_SERVICES_TEXT).val(),
                                    "roles" : roles,
                                    "userName" : $(USER_NAME_TEXT).val(),
                                    "password" : $(PASSWORD_TEXT).val()
                                   };
                                 usersPresenter.updateGroupToRoleMappings(group2rolemappingsConfig,
                                     {
                                            success :onUpdateGroup2RoleMappingSuccess,
                                            error : onError
                                      });
                              }

                        return false;
                    }
                    /**
                     * validation check for atleast one role must be selected.
                     */
                    function checkRoles() {
                      var result = false;
                        if($(SPECIALIZED_RADIO).is(':checked')) {
                          $(ROLES).each(function(index, role) {
                                 if ($(role).is(':checked')) {
                                 result = true;
                                 }
                             });

                        }else{
                         result = true;
                        }
                        return result;
                    }
                    /**
                     * load the existing roles data from the server
                     */
                    function grouprolechanged(roles){
                        $.each(roles, function(index, groupRole) {
                        if (groupRole === Localizer.getString('fs.users.common.infrastructure_administrator')){
                                $(FULL_RADIO).attr("checked", true);

                               }else if (groupRole === Localizer.getString('fs.users.common.read_only')){
                               $(READONLY_RADIO).attr("checked", true);
                               }
                               else{
                                   $(SPECIALIZED_RADIO).attr("checked", true);
                                   $(ROLES).each(function(index, role) {
                                       if ($(role).val().toLowerCase() === groupRole.toLowerCase()) {
                                           $(role).attr("checked", true);
                                       }
                                   });
                               }
                           });
                        onRoleTypeChange();
                    }
                    /**
                     * load the data for the edit group to role mapping from the server.
                     */
                    function groupChanged(groupInfo){
                    $(HEADER).html(Localizer.getString('fs.users.edit.link')+' '+groupInfo.egroup);
                    $(AUTHN_SERVICES_TEXT).val(groupInfo.loginDomain);
                    /* TODO: Escaping this '&' encoding, need to see
                     * if there is a better approach.
                     */
                    $(GROUP).val(groupInfo.egroup.replace(/&amp;/g, '&'));
                    grouprolechanged(groupInfo.roles);

                    }
                    /**
                     * @private
                     */
                    function registerEvents() {
                        usersPresenter.on('rolesChanged', updateRoles);
                        usersPresenter.on("groupChangedSuccess", groupChanged);
                     }
                    /**
                     * @private
                     */
                    function removeEvents() {
                        usersPresenter.off('rolesChanged', updateRoles);
                        usersPresenter.off("groupChangedSuccess", groupChanged);
                    }
                    /**
                     * @private
                     */
                    function validateUsersGroupForm() {
                        // role validation
                        $.validator.addMethod("GroupToRoleValidation", function(value,
                                element, param) {
                            return checkRoles();
                        }, Localizer.getString('fs.users.validations.roleValidation'));
                        validator = $(FORM).validate({
                            rules : {
                            username : {
                                    required : true

                                },
                                password : {
                                    required : true

                                },
                                role_validator : {
                                 GroupToRoleValidation : ROLE_VALIDATOR
                                }
                              }
                        });
                      }
                    /**
                     * @public Initialize the view. Makes required REST calls
                     *         and sets up event handlers.
                     */
                    this.init = function() {
                    isSubmitted = false;
                        roleTemplate = $('#fs-user-role-template').detach().removeClass('hp-template');
                        validateUsersGroupForm();
                        $(ROLE_SET).buttonset();
                        registerEvents();
                        formStateView.init({
                            form : FORM,
                            autoTrack : true
                        });
                        $(READ_ONLY_ACCESS).hide();
                        $(FULL_ACCESS).hide();
                        $(ROLES_LIST).show();
                        $(ROLE_OPTION).change(onRoleTypeChange);
                        $(ROLE_SET).change(onRoleTypeChange);
                        $(OK).on('click', function(ev) {
                            onEditGroupToRoleMappings();
                            ev.preventDefault();
                        });
                       };
                    /**
                     * @public
                     */
                    this.pause = function() {
                        removeEvents();
                        formStateView.reset();
                    };

                    /**
                     * @public
                     */
                    this.resume = function() {
                        reset();
                        registerEvents();
                      };
                   }
               return new EditDirectoryUserGroupView();

            }());

            return EditDirectoryUserGroupView;

        });
