//(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','hp/lib/jquery.hpSearchCombo' ],
        function(router, usersPresenter, authnPresenter, Localizer, session,
                FormStateView, DialogView, notifications, UsersViewUtil) {
            "use strict";

            var AddDirectoryUserGroupView = (function() {

                function AddDirectoryUserGroupView() {

                    var HEADER = '#fs-user-group-header';
                    var AUTHN_SERVICES_SELECT = "#fs-usersGroup-authn-services";
                    var AUTHN_SERVICES_TEXT = '#fs-usersGroup-authn-services-text';
                    var ROLE_VALIDATOR = '#fs-user-role-validator';
                    var ROLES_LIST = '#fs-user-roles-list';
                    var ROLES = ROLES_LIST + ' input[type="checkbox"]';
                    var ROLE = '#fs-user-role';
                    var ROLE_OPTION = 'input:radio[name=' + ROLE + ']';
                    var ROLE_SET = '#fs-user-role-set';
                    var READ_ONLY_ACCESS = '#fs-user-role-readonly-access';
                    var FULL_ACCESS = '#fs-user-role-full-access';
                    var FORM = '#fs-user-group-add-form';
                    var ADD = '#fs-add-user-group';
                    var ADD_AGAIN = '#fs-addAgain-user-group';
                    var CANCEL = '#fs-cancel-user-group';
                    var USER_NAME = '#fs-dir-credentials-username';
                    var PASSWORD = '#fs-dir-credentials-password';

                    var CRED_FORM_DLG = '#fs-dir-credentials-form-dlg';
                    var NO_DIR_CONFIGURED_FORM = '#fs-no-dir-configured';
                    var SPECIALIZED_RADIO = '#fs-user-role-specialized';
                    var READONLY_RADIO = '#fs-user-role-readonly';
                    var FULL_RADIO = '#fs-user-role-full';
                    var ADD_DIR_CONFIG_DIV = '#fs-user-group-add-div';
                    var GROUP_SELECT = '#fs-group-name-hp-select-combo';
                    var GROUP_SELECT_TEXT = '#fs-group-name-hp-select-combo-input';
                    var CONNECT = '#fs-connect';
                    var firstRoleTemplate = null, roleTemplate = null;
                    var isSpecialized, isReadOnly, isFull;
                    var credentialDialogTemplate;
                    var INFRASTRUCTURE_ADMINISTRATOR = 'Infrastructure administrator';
                    var READ_ONLY = 'Read only';

                    var validator;
                    // prevent double click
                    var isSubmitted;
                    var isCredentialsSubmitted = false, addAgain = false;
                    var confDomains, selectedLoginDomain;

                    var formStateView;

                    var userNameValue, passwordValue, authServiceValue;

                    var groupsList = [];

                    /**
                     * @private
                     */
                    function showAuthnServices() {
                        if ((confDomains === null) || (confDomains.length === 0)) {
                            // show the 'add a directory' hyperlink page
                            selectedLoginDomain = "";
                            $(NO_DIR_CONFIGURED_FORM).show();
                            $(HEADER).hide();
                            $(FORM).show();
                            $(ADD_DIR_CONFIG_DIV).hide();
                            $(ADD).hide();
                            $(ADD_AGAIN).hide();
                        } else if (confDomains.length === 1) {
                            $(NO_DIR_CONFIGURED_FORM).hide();
                            $(AUTHN_SERVICES_SELECT).empty();
                            $(AUTHN_SERVICES_SELECT).selectBox('destroy');
                            $(AUTHN_SERVICES_SELECT).hide();
                            $(AUTHN_SERVICES_TEXT).show();
                            $(HEADER).show();
                            $(FORM).show();
                            $(ADD_DIR_CONFIG_DIV).show();
                            $(ADD).show();
                            $(ADD_AGAIN).show();
                            $(AUTHN_SERVICES_TEXT).val(confDomains[0].name);
                            selectedLoginDomain = confDomains[0].name;
                        } else {
                            $(NO_DIR_CONFIGURED_FORM).hide();
                            $(AUTHN_SERVICES_TEXT).hide();
                            $(HEADER).show();
                            $(FORM).show();
                            $(AUTHN_SERVICES_SELECT).empty();
                            $(AUTHN_SERVICES_SELECT).selectBox('destroy');
                            $.each(confDomains, function(index, domain) {
                                $(AUTHN_SERVICES_SELECT).append($('<option>', {
                                    value : domain.loginDomain
                                }).text(domain.name));
                            });
                            $(AUTHN_SERVICES_SELECT).selectBox({
                                autoWidth : false
                            });
                            $(AUTHN_SERVICES_SELECT).val(
                                    confDomains[0].loginDomain);
                            $(AUTHN_SERVICES_SELECT).selectBox('reset');
                            selectedLoginDomain = confDomains[0].name;
                        }
                    }

                    /**
                     * @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 onGetGlobalSettingsSuccess(configuredDomains) {
                        confDomains = configuredDomains;
                        showAuthnServices();
                    }

                    /**
                     * @private
                     */
                    function formatNotificationDetails(serverError) {

                        var resolutionList = serverError.recommendedActions;
                        var resolutionMessage = "";
                        $.each(resolutionList, function(index, resolution) {
                            resolutionMessage = resolutionMessage + resolution + " <br> ";
                        });

                        var failureNotificationDetails = {
                            summary : Localizer.getString('fs.users.add.add'),
                            sourceName : $(GROUP_SELECT_TEXT).val(),
                            uri : "addGroupError-"+ (new Date()).getTime(),
                            details : serverError.message + " " + resolutionMessage + '\n' + serverError.details,
                            status : "error"
                        };
                        return failureNotificationDetails;
                    }

                    /**
                     * @private
                     */
                    function onError(errorInfo) {
                        var details = '';
                        var resolutions = '';
                        var failureNotificationDetails = '';
                        var serverErrorList = errorInfo.nestedErrors;
                        if(serverErrorList.length === 0) {
                            details = errorInfo.details;
                            resolutions = errorInfo.resolution;
                        } else {
                        $.each(
                            serverErrorList,
                            function(index, serverError) {
                                details = details + " " +serverError.details;
                                var resolutionList = serverError.recommendedActions;
                                failureNotificationDetails = formatNotificationDetails(serverError);
                                $.each(
                                    resolutionList,
                                    function(index,
                                        resolution) {
                                        resolutions = resolutions + " " + resolution;
                                    });
                            });
                         }
                        formStateView.setMessage({
                            summary : details,
                            status : 'error',
                            details : resolutions
                        });

                        notifications.add(failureNotificationDetails, true,
                                true, true);

                        isSubmitted = false;
                    }

                    /**
                     * @private
                     */
                    function onSpecializedUserClick() {
                        $(SPECIALIZED_RADIO).attr("checked", true);
                        isSpecialized = true;
                        isReadOnly = false;
                        isFull = false;
                        $(READ_ONLY_ACCESS).hide();
                        $(FULL_ACCESS).hide();
                        $(ROLES_LIST).show();
                        autoCheckSpecializedRole(true);
                    }

                    /**
                     * @private
                     */
                    function onReadOnlyUserClick() {
                        $(READONLY_RADIO).attr("checked", true);
                        isSpecialized = false;
                        isReadOnly = true;
                        isFull = false;
                        $(READ_ONLY_ACCESS).show();
                        $(FULL_ACCESS).hide();
                        autoCheckSpecializedRole(false);
                        $(ROLES_LIST).hide();
                    }

                    /**
                     * @private
                     */
                    function onFullUserClick() {
                        $(FULL_RADIO).attr("checked", true);
                        isSpecialized = false;
                        isReadOnly = false;
                        isFull = true;
                        $(READ_ONLY_ACCESS).hide();
                        $(FULL_ACCESS).show();
                        autoCheckSpecializedRole(false);
                        $(ROLES_LIST).hide();
                    }

                    /**
                     * @private
                     */
                    function onRoleTypeChange() {
                        if ($(
                                'input[type="radio"][name=' + "fs-user-role" + ']:checked').attr('id') === $(
                                SPECIALIZED_RADIO).attr('id')) {
                            onSpecializedUserClick();
                        } else if ($(
                                'input[type="radio"][name=' + "fs-user-role" + ']:checked').attr('id') === $(
                                READONLY_RADIO).attr('id')) {
                            onReadOnlyUserClick();
                        } else if ($(
                                'input[type="radio"][name=' + "fs-user-role" + ']:checked').attr('id') === $(
                                FULL_RADIO).attr('id')) {
                            onFullUserClick();
                        }
                    }

                    /**
                     * @private
                     */
                    function onAuthnServiceChange() {
                        selectedLoginDomain = $(
                                AUTHN_SERVICES_SELECT + " :selected").text();
                        isCredentialsSubmitted = false;
                        setDefaultGroupSelect();
                        resetCredentials();
                        $(USER_NAME).focus();
                    }

                    /**
                     * @private
                     */
                    function reset() {
                        // Initialize the combo box and clears it
                        $(ROLES).each(function(index, role) {
                            if (isSpecialized) {
                                role.checked = false;
                            }
                        });
                        onSpecializedUserClick();
                        $(GROUP_SELECT_TEXT).val("");
                        isCredentialsSubmitted = false;
                        isSubmitted = false;
                        formStateView.reset();
                    }

                    /**
                     * @private
                     */
                    function onAddSuccess() {
                        var alertMsgSuccess = Localizer.getString(
                                'fs.users.userGroup.success',
                                [ $(GROUP_SELECT_TEXT).val() ]);
                        formStateView.setMessage({
                            summary : alertMsgSuccess,
                            status : 'ok',
                            alertMsg : alertMsgSuccess
                        });

                        var grpAddedSuccess = {
                            summary : Localizer.getString('fs.users.add.add'),
                            sourceName : $(GROUP_SELECT_TEXT).val(),
                            uri : "groupAddTsk-" + $(GROUP_SELECT_TEXT).val() + (new Date()).getTime(),
                            status : "ok",
                            details : alertMsgSuccess
                        };
                        notifications.add(grpAddedSuccess, true, true, true);
                        reset();
                        if (!addAgain) {
                            resetCredentials();
                            setDefaultGroupSelect();
                            router.go('/user/show', 'user show');
                        }
                    }

                    /**
                     * @private
                     */
                    function onAddGroupToRoleMappings() {
                            if ($(FORM).valid()) {
                                var roles = [];
                                if (isSpecialized) {
                                    $(ROLES).each(function(index, role) {
                                        if ($(role).is(':checked')) {
                                            roles.push($(role).val());
                                        }
                                    });
                                } else if (isReadOnly) {
                                    roles
                                            .push(Localizer
                                                    .getString('fs.users.userGroup.readonly'));
                                } else if (isFull) {
                                    roles
                                            .push(Localizer
                                                    .getString('fs.users.userGroup.infrastructureAdministrator'));
                                }

                                if (roles !== null) {
                                    var group = $(GROUP_SELECT_TEXT).val();
                                    var userName = $(USER_NAME).val();
                                    var password = $(PASSWORD).val();;
                                    if (confDomains.length === 1) {
                                        selectedLoginDomain = $(
                                                AUTHN_SERVICES_TEXT).val();
                                    }
                                    var alertMsgAdd = Localizer.getString('fs.users.userGroup.add_message', [$(GROUP_SELECT_TEXT).val()]);
                                    formStateView.setMessage({summary:alertMsgAdd, status:'info', changing : true});

                                    authnPresenter.addGroupToRoleMappings(
                                            selectedLoginDomain, group, roles,
                                            userName, password, {
                                                success : onAddSuccess,
                                                error : onError
                                            });
                                }
                                return true;
                            }
                        return false;
                    }

                    /**
                     * @private
                     */
                    function updateRoles() {
                        var roles = usersPresenter.getRoles();

                        $(ROLES_LIST).empty();

                        $.each(roles, function(index, role) {
                            if (role.roleName !== 'No_Privileges' && role.roleName !== INFRASTRUCTURE_ADMINISTRATOR 
                                && role.roleName !== READ_ONLY) {
                                var item = null;
                                if (index === 0) {
                                    item = firstRoleTemplate.clone();
                                } else {
                                    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", {
                                        roleValidation : ROLE_VALIDATOR
                                    });
                                }

                            }
                        });
                        autoCheckSpecializedRole(true);
                        formStateView.reset();

                    }

                    /**
                     * @private
                     */
                    function checkRoles() {
                        var result = false;
                        $(ROLES).each(function(index, role) {
                            if (isSpecialized) {
                                if ($(role).is(':checked')) {
                                    result = true;
                                }
                            } else {
                                result = true;
                            }
                        });
                        return result;
                    }

                    /**
                     * @private
                     */
                    function registerEvents() {
                        usersPresenter.on("onCompleteGlobalSettings",
                                onGetGlobalSettingsSuccess);
                        usersPresenter.on("getGlobalSettingsError", onError);
                        usersPresenter.on('rolesChanged', updateRoles);
                    }

                    /**
                     * @private
                     */
                    function removeEvents() {
                        usersPresenter.off("onCompleteGlobalSettings",
                                onGetGlobalSettingsSuccess);
                        usersPresenter.off("getGlobalSettingsError", onError);
                        usersPresenter.off('rolesChanged', updateRoles);
                    }

                    /**
                     * @private
                     */
                    function cancel() {
                        reset();
                    }

                    function onGetGroupsSuccess(groupsList) {
                        var itemList = [];
                        $.each(groupsList, function(index, group) {
                             /*
                             * TODO: Escaping this '&' encoding, need to
                             * see if there is a better approach.
                             */
                            group = group.replace(/&amp;/g, '&');
                            var item = {id: index+1, name: group};
                            itemList.push(item);
                        });
                        $(GROUP_SELECT).hpSearchCombo('destroy');
                        $(GROUP_SELECT).hpSearchCombo({results: itemList,
                            searchingMessage: Localizer.getString('search.searching'),
                            noMatchesMessage: Localizer.getString('search.noMatches'),
                            matchesMessage: Localizer.getString('search.matches')});
                            $(GROUP_SELECT_TEXT).focus();
                            formStateView.reset();
                    }

                    function onGetGroupsFailure(errorMessage) {
                        isCredentialsSubmitted = false;
                        formStateView.setMessage({
                            summary : errorMessage.details,
                            status : 'error',
                            details : errorMessage.resolution
                        });
                    }

                    function getGroupList() {
                        var uname = userNameValue;
                        var password = passwordValue;
                        var authDomain = authServiceValue;
                        usersPresenter.getGroupList(uname,
                                password,
                                authDomain,
                                {
                            success : onGetGroupsSuccess,
                            error: onGetGroupsFailure
                        });
                    }

                    function setGroupSelectData() {
                        groupsList = getGroupList();
                    }

                    /**
                     * @private
                     */
                    function onConnect() {
                        userNameValue = $(USER_NAME).val();
                        passwordValue = $(PASSWORD).val();
                        authServiceValue = $(AUTHN_SERVICES_SELECT + " :selected").text();
                        if(authServiceValue === "") {
                            authServiceValue = $(AUTHN_SERVICES_TEXT).val();
                        }
                        isCredentialsSubmitted = true;
                        formStateView.reset();
                        var alertMsgGroupName = Localizer.getString('fs.users.userGroup.loadingGroupName');
                        formStateView.setMessage({summary:alertMsgGroupName, status:'info', changing : true});
                        setGroupSelectData();
                        return isCredentialsSubmitted;
                    }

                    /**
                     * @private
                     */
                    function credentialsCall() {
                        if ($(FORM).valid()){
                            if(isCredentialsSubmitted === false) {
                                onConnect();
                            } else {
                                var alertMsgConnected = Localizer
                                .getString('fs.users.credentials.success', [$(USER_NAME).val()]);
                                formStateView.setMessage({
                                    summary : alertMsgConnected,
                                    status : 'unknown',
                                    alertMsg : alertMsgConnected
                                });
                            }
                        }
                    }

                    /**
                     * @private
                     */
                    function validateCredentials() {
                        if($(USER_NAME).val() === '' || $(PASSWORD).val() === '') {

                        validator = $(FORM).validate({
                            errorPlacement : function(error,element) {
                                $("div#fs-authn-credentials-error").append(error).show();
                            }
                        });
                        validator.groups.username = 'credentials';
                        validator.groups.password = 'credentials';

                        $(USER_NAME).rules("add", {
                                            required : true,
                                            messages : {
                                                required : Localizer.getString('fs.users.userGroup.required')
                                            }
                                        });

                        $(PASSWORD).rules("add", {
                                            required : true,
                                            messages : {
                                                required : Localizer.getString('fs.users.userGroup.required')
                                            }
                                        });
                        }
                    }

                    function setDefaultGroupSelect() {
                        $(GROUP_SELECT_TEXT).val("");
                        $(GROUP_SELECT).hpSearchCombo({results: {count:0,total:0,start:0,members:[]}});
                        $(GROUP_SELECT).hpSearchCombo('set');
                    }

                    function resetCredentials() {
                        $(USER_NAME).val("");
                        $(PASSWORD).val("");
                    }

                    /**
                     * @private
                     */
                    function initForm() {
                        isSubmitted = false;
                        isCredentialsSubmitted = false;
                        $(USER_NAME).focus();
                        credentialDialogTemplate = $(CRED_FORM_DLG).detach()
                                .show();
                        Localizer.localizeDom(credentialDialogTemplate);
                        $(GROUP_SELECT).hpSearchCombo('destroy');
                        setDefaultGroupSelect();
                    }


                    /**
                     * @public Initialize the view. Makes required REST calls
                     *         and sets up event handlers.
                     */
                    this.init = function() {
                        firstRoleTemplate = $('#fs-user-first-role-template')
                                .detach();
                        roleTemplate = $('#fs-user-role-template').detach();
                        $(ROLE_SET).buttonset();
                        initForm();

                        formStateView = new FormStateView();
                        formStateView.init({
                            form : FORM,
                            autoTrack : true
                        });

                        isSpecialized = true;
                        isReadOnly = false;
                        isFull = false;
                        $(READ_ONLY_ACCESS).hide();
                        $(FULL_ACCESS).hide();
                        $(ROLES_LIST).show();
                        $(NO_DIR_CONFIGURED_FORM).css({
                            position : "absolute",
                            zIndex : "2",
                            width : "2.5em",
                            height : "1.2em",
                            cursor : "default",
                            top : "10px",
                            left : "50px",
                            bottom : "10px",
                            right : "10px",
                            marginLeft : "0.6em",
                            background : "#e6e6e6",
                            fontWeight : "normal",
                            color : "#555555",
                            textDecoration : "none"
                        });
                        $(NO_DIR_CONFIGURED_FORM).hide();

                        $(ROLE_OPTION).change(function(e) {
                            onRoleTypeChange();
                        });

                        $(ROLE_SET).change(function(e) {
                            onRoleTypeChange();
                        });

                        $(AUTHN_SERVICES_SELECT).change(function() {
                            onAuthnServiceChange();
                        });

                        $(ADD).on('click', function(ev) {
                            validateCredentials();
                            addAgain = false;
                            onAddGroupToRoleMappings.call(this);
                            ev.preventDefault();
                        });

                        $(ADD_AGAIN).on('click', function(ev) {
                            validateCredentials();
                            addAgain = true;
                            onAddGroupToRoleMappings.call(this);
                            ev.preventDefault();
                        });

                        $(CANCEL).click(function() {
                            cancel();
                        });
                        $(CONNECT).click(function(evt) {
                            validateCredentials();
                            credentialsCall();
                            evt.preventDefault();
                        });
                        $(USER_NAME).change(function(evt) {
                            isCredentialsSubmitted = false;
                        });
                        $(PASSWORD).change(function(evt) {
                            isCredentialsSubmitted = false;
                        });
                        registerEvents();
                        usersPresenter.getAuthnServices();
                        $(USER_NAME).focus();
                    };

                    /**
                     * @public
                     */
                    this.pause = function() {
                        removeEvents();
                        formStateView.reset();
                    };

                    /**
                     * @public
                     */
                    this.resume = function() {
                        registerEvents();
                        onAuthnServiceChange();
                        usersPresenter.getAuthnServices();
                        updateRoles();
                        $(GROUP_SELECT).hpSearchCombo('destroy');
                        setDefaultGroupSelect();
                    };

                }
                return new AddDirectoryUserGroupView();

            }());

            return AddDirectoryUserGroupView;

        });