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

            var AuthnAddDirectoryView = (function() {

                var ADD_DIR_SERVER_BUTTON = '#fs-settings-authn-add-dir-servers',
                    FORM = '#fs-settings-authentication-add-form',
                    DIR_NAME_TEXT = '#fs-settings-authn-dir-name-text',
                    TYPE_SELECT = ".fs-settings-authn-dir-type-select",
                    UID_TEXT = '.fs-settings-authn-search-context-uid-text',
                    ORG_TEXT = '.fs-settings-authn-search-context-org-text',
                    TOP_TEXT = '.fs-settings-authn-search-context-top-text',
                    USER_NAME_TEXT = '#fs-settings-authn-user-name-text',
                    PASSWORD_TEXT = '#fs-settings-authn-password-text',
                    HOST_NAME_ERROR = '#fs-settings-authn-dir-server-text-error',
                    ADD_BUTTON_FOR_DIR = '#fs-authn-add-dir-add',
                    ADD_AGAIN_BUTTON_FOR_DIR = '#fs-authn-add-dir-addAgain',
                    CANCEL_BUTTON_FOR_DIR = '#fs-cancel-add-dir',
                    ADD_DIR_SERVER_DLG = '#fs-authn-add-dir-server-dlg',
                    ADD_DIR_SERVER_FORM = '#fs-authn-add-dir-server-form',
                    HOST_NAME = '#fs-settings-authn-host-name-text',
                    SSL_PORT = '#fs-settings-authn-port-text',
                    KEY = '#fs-settings-authn-certificate',
                    DIR_SERVERS_TABLE = '#fs-dir-servers-table',
                    ADD_DIRSERVERS_HEADER = "#add_dir_server_header",
                    ADD_DIRSERVERS_FOOTER = "#add-dir-server-footer",
                    EDIT_DIRSERVERS_HEADER = "#edit_dir_server_header",
                    EDIT_DIRSERVERS_FOOTER = "#edit-dir-server-footer",
                    DUPLICATEHOST_ERROR = '#fs-settings-authn-hostname-duplicate-error',
                    CREDENTIALS_TEXT_MSG = '#fs-settings-authn-credentials-text',
                    ROUTE_PREFIX = '/settings/directory/add',
                    HELP_TEXT = '#fs-settings-authn-search-context-help';
                /**
                 * @class View script for the Add Directory page.
                 */
                function AuthnAddDirectoryView() {

                    var addDirServerDlgTemplate = null,
                    addDirAgain = false,
                    dirFormStateView = new FormStateView(),
                    serverFormStateView = new FormStateView(),
                    directoryValidator = null,
                    serverValidator = null,
                    entries = [],
                    serversTable = null,
                    currentRow = 0,
                    serversList = [],
                    serverDto = null,
                    errorInUID = false,
                    dirErrorCount = 0,
                    rowlength = 0,
                    serverErrorCount = 0,
                    validateAddDirServerIP = true,
                    addAgainDirectory = false,
                    dialog = null,
                    editRow = null,
                    productConfigMembersData = null;
                    /**
                     * Delete the directory sever
                     */
                    function onDeleteAddDirServer(event) {
                      if( !event.isPropagationStopped()){
                        var row = $(this).parents('tr')[0];
                        var entry = serversTable.fnGetData(row);
                        if(!entry) {
                            return;
                        }
                        entries = $.grep(entries, function (entry2) {
                            return entry2.id !== entry.id;
                        });

                        serversList = $.grep(serversList, function (sentry2) {
                            return sentry2.directoryServerIpAddress !== entry.name;
                        });

                        var alertMsg = Localizer.getString(
                                'fs.settings.authn.addDirectory.remove_server_success', [entry.name]);
                        dirFormStateView.setMessage({
                            summary : alertMsg,
                            status : 'ok',
                            alertMsg : alertMsg
                        });

                        serversTable.fnDeleteRow(row);
                        serversTable.fnDraw();

                        rowlength = rowlength-1;
                        if(serversList.length === 0) {
                            rowlength = 0;
                            $(DIR_SERVERS_TABLE).hide();
                        }
                        event.stopPropagation();
                        event.preventDefault();
                        }
                      }
                    /**
                     * show directory server dialog
                     */
                    function onAddDirServer() {
                       dialog = new DialogView({
                            contents : addDirServerDlgTemplate,
                            ok: function(button) {

                             },
                            cancel: function() {
                                  if ($(ADD_DIR_SERVER_DLG).is(':data(dialog)')) {
                                   $(ADD_DIR_SERVER_DLG).dialog("close");
                               }

                                }
                        });
                        dialog = dialog;
                        $(HOST_NAME).focus();
                        $(KEY).attr("placeholder", Localizer.getString('fs.settings.authn.addDirectory.certificate_placeholder'));
                    }
                    /**
                     * @private
                     */
                    function onEditAddDirServer(event) {
                        validateAddDirServerIP = false;
                    if( !event.isPropagationStopped()){
                        var row = $(this).parents('tr')[0];
                        var association = serversTable.fnGetData(row);
                        editRow = row ;
                        resetServerParams();
                        $(HOST_NAME, addDirServerDlgTemplate).val(association.name);
                        $(SSL_PORT, addDirServerDlgTemplate).val(association.port);
                        $(KEY, addDirServerDlgTemplate).val(association.certificate);
                        $(ADD_DIRSERVERS_HEADER, addDirServerDlgTemplate).hide();
                        $(ADD_DIRSERVERS_FOOTER, addDirServerDlgTemplate).hide();
                        $(EDIT_DIRSERVERS_HEADER, addDirServerDlgTemplate).show();
                        $(EDIT_DIRSERVERS_FOOTER, addDirServerDlgTemplate).show();
                        serverValidator.resetForm();
                        onAddDirServer();
                    }
                      event.stopPropagation();
                      event.preventDefault();
                      }
                    /**
                     * @private
                     */
                    function initServersTable() {
                        entries = [];
                        serversTable = $(DIR_SERVERS_TABLE).dataTable({
                            bPaginate : false,
                            bFilter : false,
                            bInfo : false,
                            sScrollXInner : "100%",
                            bScrollCollapse : true,
                            bDestroy : true,
                            bAutoWidth: false,
                            aaData : entries,
                            aoColumns : [
                             {
                                sTitle : Localizer.getString('fs.settings.authn.addServer.table_column_server'),
                                mDataProp : 'name',
                                sWidth : 20
                            }, {
                                sTitle : Localizer.getString('fs.settings.authn.addServer.table_column_certificate'),
                                mDataProp : 'status',
                                sWidth : 20
                            },
                            {
                               sTitle : 'port',
                                mDataProp : 'port',
                                sWidth : 5,
                                bVisible : false
                            },
                            {
                                    sTitle : 'certificate',
                                    mDataProp : 'certificate',
                                    sWidth : 5,
                                    bVisible : false
                                },
                            {
                                fnRender : function(oObj) {
                                    return '<div class="hp-edit"></div>';
                                },
                                sDefaultContent : '',
                                sClass : 'hp-icon',
                                sWidth : 5,
                                bSortable : false
                            }, {
                                fnRender : function(oObj) {
                                    return '<div class="hp-close"></div>';
                                },
                                sDefaultContent : '',
                                sClass : 'hp-icon',
                                sWidth : 5,
                                bSortable : false
                            }
                          ]
                        });

                        $(DIR_SERVERS_TABLE).on('click', '.hp-close', onDeleteAddDirServer);
                        $(DIR_SERVERS_TABLE).on('click', '.hp-edit', onEditAddDirServer);
                    }

                    /**
                     * @private Add a server side error to the list of errors that the validator will display
                     * @param {object} validatorErrors The list of errors that the validator will display
                     * @param {object} errorFromServer The error from a REST response body to add to the list
                     */
                    function addValidatorError(validatorErrors, errorFromServer) {
                        var errorMessage = errorFromServer.message;
                        var sourceId = errorFromServer.errorSource;
                        var validatorErrorsMap = {
                            "dirname" : "name",
                            "type" : "authProtocol",
                            "uid" : "userNameField",
                            "org" : "org",
                            "top" : "top",
                            "servers" : "directoryServers",
                            "port" : "portNumber"
                        };

                        $.map(validatorErrorsMap, function(value, key) {
                            if(sourceId === value) {
                                validatorErrors[key] = errorMessage;
                                if(value.match("portNumber")) {
                                    serverErrorCount++;
                                }
                                else {
                                    dirErrorCount++;
                                }
                            }
                        });

                        if(sourceId.indexOf("server:") === 0) {
                            validatorErrors.username = errorMessage;
                            dirErrorCount++;
                        }
                        else if(sourceId.indexOf("certificate") === 0) { // cerificate expired && cerificate
                            validatorErrors.publickey = errorMessage;
                            serverErrorCount++;
                        }
                        else if(sourceId.indexOf("ipAddress") === 0) { // ipAddress && ipAddress:portNumber
                            validatorErrors.hostname = errorMessage;
                            serverErrorCount++;
                        }
                        else if(sourceId.indexOf("org") === 0) { // org contains more than 4 entries
                            validatorErrors.org = errorMessage;
                            serverErrorCount++;
                        }
                    }
                    /**
                     * @private
                     */
                 function formatNotificationDetails(serverError) {
                    var resolutionList = serverError.recommendedActions;
                    var resolutionMessage = "";
                      $.each(resolutionList, function(index, resolution) {
                          serverError.recommendedActions.join('<br>');
                             resolutionMessage = serverError.recommendedActions.join('<br>');
                            });
                        var failureNotificationDetails = {
                         summary : serverError.message
                                    + " "
                                    + (resolutionMessage),
                               details : serverError.details,
                               status : "error"
                        };
                        return failureNotificationDetails;
                    }
                    /**
                     * @private
                     */
                    function onAddDirError(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 += serverError.recommendedActions.join('<br>');
                              });
                        });
                       }else {
                           details = errorInfo.details ;
                           resolutions = errorInfo.resolution;
                       }
                       dirFormStateView.setMessage({
                            summary : details,
                            status : 'error',
                            details : resolutions
                        });

                    }

                    /**
                     * @private
                     */
                    function resetServerParams() {
                        $(HOST_NAME).val("");
                        $(SSL_PORT).val("");
                        $(KEY).val("");
                        $(HOST_NAME_ERROR).removeClass('hp-error');
                        $(HOST_NAME_ERROR).parent().removeClass('hp-has-error');
                        $(HOST_NAME_ERROR).text('');
                        $(HOST_NAME_ERROR).hide();
                        serverValidator.resetForm();
                        serverErrorCount = 0;
                    }

                    /**
                     * add directory server success
                     */
                    function onAddServerSuccess() {
                        // get host name from the text field
                        var serverHost = $(HOST_NAME).val();
                        var port = $(SSL_PORT).val();
                        var certificate = $(KEY).val();
                        var rowId = rowlength+1;
                        var row = [{id:rowId, name:serverHost, status:Localizer.getString('fs.settings.authn.addServer.certificate_state_yes'),
                            port:port,certificate:certificate}];
                        serversTable.fnAddData(row);
                        serversTable.fnAdjustColumnSizing();
                        serversTable.fnDraw();
                        $(DIR_SERVERS_TABLE).css("display", "block");
                        $(DIR_SERVERS_TABLE).show();

                        serversList.push(serverDto);

                        //Change : Directory servers to 'server name'
                        var alertMsg = Localizer.getString('fs.settings.authn.addServer.success', [serverHost]);
                        notifications.add({ summary : alertMsg, status : 'ok' }, true);

                        serverFormStateView.setMessage({
                            summary : alertMsg,
                            status : 'ok',
                            alertMsg : alertMsg
                        });

                        // reset the params
                        resetServerParams();
                        if(!addAgainDirectory){
                           dialog.cancel();
                        }

                    }

                    /**
                     * validate directory server params
                     */
                    function addDirServer(button){
                       var close = $(button).hasClass('hp-primary'); // false means leave dialog open
                       if ($(ADD_DIR_SERVER_FORM).valid()) {
                         serverDto = {
                               "type" : "LoginDomainDirectoryServerInfoDto",
                               "directoryServerSSLPortNumber" : $(SSL_PORT).val(),
                               "directoryServerIpAddress" : $(HOST_NAME).val(),
                               "directoryServerCertificateStatus" : "",
                               "serverStatus" : "",
                               "directoryServerCertificateBase64Data" : $(KEY).val()
                           };
                             onAddServerSuccess();
                         if(close) {
                           dialog.cancel();
                         }
                       }

                       return false;

                    }
                    /**
                     * add directory server success
                     */
                    function onEditServerSuccess() {
                     // get host name from the text field
                     var serverHost = $(HOST_NAME).val();
                     var port = $(SSL_PORT).val();
                     var certificate = $(KEY).val();
                     var association = serversTable.fnGetData(editRow);
                     $.each(serversList, function(index, servers) {
                           if(this.directoryServerIpAddress === association.name){
                               serversList.splice(index,1,serverDto);
                          }
                      });
                     serversTable.fnUpdate(serverHost, editRow, 0, false );
                     serversTable.fnUpdate(port, editRow, 2, false );
                     serversTable.fnUpdate(certificate, editRow, 3, false );
                     serversTable.fnDraw();
                    //Change : Directory servers to 'server name'
                     var alertMsg = Localizer.getString('fs.settings.authn.addServer.success', [serverHost]);
                     serverFormStateView.setMessage({
                            summary : alertMsg,
                            status : 'ok',
                            alertMsg : alertMsg
                        });

                        // reset the params
                        resetServerParams();
                        if(!addAgainDirectory){
                           dialog.cancel();
                        }

                    }
                    /**
                     * duplicate directory server check while editing the server
                     */
                    function isDuplicateServer(){
                        var result = true;
                        var hostname = $(HOST_NAME).val();
                        var editData = serversTable.fnGetData(editRow);
                        if(editData.name !== hostname){
                        $.each(serversList, function(index, servers) {
                            if(hostname === servers.directoryServerIpAddress){
                                  result  = false;
                                  return false ;
                              }
                          });
                        }
                        return result;
                    }
                    /**
                     * validate directory server params
                     */
                    function editDirServer(button){
                       var close = $(button).hasClass('hp-primary'); // false means leave dialog open
                         if ($(ADD_DIR_SERVER_FORM).valid() && isDuplicateServer()) {
                         serverDto = {
                               "type" : "LoginDomainDirectoryServerInfoDto",
                               "directoryServerSSLPortNumber" : $(SSL_PORT).val(),
                               "directoryServerIpAddress" : $(HOST_NAME).val(),
                               "directoryServerCertificateStatus" : "",
                               "serverStatus" : "",
                               "directoryServerCertificateBase64Data" : $(KEY).val()
                           };
                                   onEditServerSuccess();
                                   if(close) {
                                       dialog.cancel();
                                   }

                       }
                       else if(!isDuplicateServer()) {
                           $(DUPLICATEHOST_ERROR).text(Localizer.getString('fs.settings.authn.addServer.duplicate_host'));
                           $(DUPLICATEHOST_ERROR).addClass('hp-error');
                           $(DUPLICATEHOST_ERROR).parent().addClass('hp-has-error');
                           $(DUPLICATEHOST_ERROR).show();
                           }
                       return false;

                    }


                    function checkIfAtleastOneDirServer() {
                        // check if user has provided at least one directory server
                        // for the login domain
                        if(serversList.length === 0) {
                            $(HOST_NAME_ERROR).text(Localizer.getString('fs.settings.authn.edit.directory_server_required_error'));
                            $(HOST_NAME_ERROR).addClass('hp-error');
                            $(HOST_NAME_ERROR).parent().addClass('hp-has-error');
                            $(HOST_NAME_ERROR).show();

                            return false;
                        }

                        return true;
                    }
                    /**
                     * @private
                     */
                    function resetDirParams() {
                        $(DIR_NAME_TEXT).val("");
                        $(UID_TEXT).val("");
                        $(ORG_TEXT).val("");
                        $(TOP_TEXT).val("");
                        $(USER_NAME_TEXT).val("");
                        $(PASSWORD_TEXT).val("");
                        if(serversList.length > 0) {
                            $.each(serversList, function(index, server) {
                                serversTable.fnDeleteRow(index);
                            });
                            serversList = [];
                            currentRow = 0;
                        }
                        serversTable.fnDraw();
                        $(DIR_SERVERS_TABLE).hide();
                        directoryValidator.resetForm();
                        dirErrorCount = 0;
                    }

                    /**
                     * @private
                     */
                    function onAddDirSuccess() {
                        var alertMsg = Localizer.getString(
                                'fs.settings.authn.addDirectory.add_success', [$(DIR_NAME_TEXT).val()]);
                        dirFormStateView.setMessage({
                            summary : alertMsg,
                            status : 'ok',
                            alertMsg : alertMsg
                        });

                        var dirAddedSuccess = {
                            summary : Localizer.getString('fs.settings.authn.addDirectory.success_notification'),
                            status : "ok"
                        };
                        notifications.add(dirAddedSuccess, true, true, true);

                        resetDirParams();
                        if (!addDirAgain) {
                            $(CANCEL_BUTTON_FOR_DIR).trigger('click');
                         }
                    }

                    /**
                     * @private
                     */
                    function onAddDirectory() {
                        // call the post API to add a directory
                        // on success
                        if ($(FORM).valid() && checkIfAtleastOneDirServer()) {

                            var dirConfig = {
                                    "name" : $(DIR_NAME_TEXT).val(),
                                    "userName" : $(USER_NAME_TEXT).val(),
                                    "password" : $(PASSWORD_TEXT).val(),
                                    "authProtocol" : $(TYPE_SELECT + " :selected").val(),
                                    "org" : $(ORG_TEXT).val(),
                                    "top" : $(TOP_TEXT).val(),
                                    "userNameField" : $(UID_TEXT).val(),
                                    "directoryServers" : serversList
                                };

                            presenter.addDirectory(dirConfig, {
                                success : onAddDirSuccess,
                                error : onAddDirError
                            });
                        }else if(checkIfAtleastOneDirServer()){
                            var error = {
                                "errorMessage" : Localizer.getString('fs.settings.authn.edit.save_failure'),
                                "resolution" : Localizer.getString('fs.settings.authn.edit.failure_resolution')
                            };
                            dirFormStateView.setMessage({
                                summary : error.errorMessage,
                                status : 'error'
                            });

                        }

                    }
                    /**
                     * Loads the product-config data
                     */
                    function loadProductConfigData(){
                        ProductConfig.getproductConfigMembers({
                            success : function(productConfigMembers) {
                                productConfigMembersData = productConfigMembers;
                            }
                        });
                    }
                    /**
                     * @private
                     */
                    function onCancelDirectory() {
                        resetDirParams();
                        dirFormStateView.reset();
                    }

                    /**
                     * @private
                     */
                    function validateServerForm() {

                        /*
                         * Regex for Hostname
                         * (?=^.{1,254}$) matches domain names (that can begin with any char) that are long
                         * between 1 and 254 char, it could be also 5,254 if we assume co.uk is the minimum length.
                         * (^ starting match
                         * (?: define a matching group
                         * (?!\d+\.) the domain name should not be composed by numbers, so 1234.co.uk or abc.123.uk
                         * aren't accepted while 1a.ko.uk yes.
                         * [a-zA-Z0-9_\-] the domain names should be composed by words with only a-zA-Z0-9_-
                         * {1,63} the lenght of any domain level is maximum 63 char, (it could be 2,63)
                         * + and
                         * (?:[a-zA-Z]{2,})$) the final part of the domain name should not be followed by any other
                         * word and must be composed of a word minumum of 2 char a-zA-Z
                         *
                         * Also checks for dotted notation for a valid IP address check - xxx.xxx.xxx.xxx where
                         * xxx can be anything between 0 and 255
                         */
                        $.validator.addMethod("fsDirServerHostCheck", function(value, element, param) {
                            return (/^(([01]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])\.){3}([01]?[0-9]{1,2}|2[0-4][0-9]|25[0-5])$/
                                                    .test(value) ||
                                    /(?=^.{1,254}$)(^(?:(?!\d+\.)[a-zA-Z0-9\-]{1,63}\.?)+(?:[a-zA-Z]{2,})$)/.test(value)) ||
                              /^\s*((([0-9A-Fa-f]{1,4}:){7}(([0-9A-Fa-f]{1,4})|:))|(([0-9A-Fa-f]{1,4}:){6}(:|((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})|(:[0-9A-Fa-f]{1,4})))|(([0-9A-Fa-f]{1,4}:){5}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){4}(:[0-9A-Fa-f]{1,4}){0,1}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){3}(:[0-9A-Fa-f]{1,4}){0,2}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){2}(:[0-9A-Fa-f]{1,4}){0,3}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:)(:[0-9A-Fa-f]{1,4}){0,4}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(:(:[0-9A-Fa-f]{1,4}){0,5}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})))(%.+)?\s*$/.test(value);
                        }, Localizer.getString('fs.settings.authn.addServer.invalid_host'));

                        $.validator.addMethod("notDuplicateFsDirSever", function(value, element) {
                            var duplicate = false;
                            if(validateAddDirServerIP){
                            for(var i = 0; i < serversList.length; i++) {
                                if(value.match(serversList[i].directoryServerIpAddress))
                                {
                                    duplicate = true;
                                }
                            }
                            }
                            return (!duplicate);
                        }, Localizer.getString('fs.settings.authn.addServer.duplicate_host'));

                        $.validator.addMethod("fsDirServerPortNumericCheck",function(value, element) {
                            return (/^[\d]+$/.test(value));
                        }, Localizer.getString('fs.settings.authn.addServer.invalid_port'));

                        $.validator.addMethod("fsDirServerPortInRangeCheck",function(value, element) {
                            return (value >= 0 && value <= 65535);
                        }, Localizer.getString('fs.settings.authn.addServer.invalid_port_range'));

                        $.validator.addMethod("fsDirServerCertCheck",function(value, element) {
                            return (value.match("^-----BEGIN") &&
                                    value.match("END CERTIFICATE-----$"));
                        }, Localizer.getString('fs.settings.authn.addServer.invalid_certificate'));

                       serverValidator = $(ADD_DIR_SERVER_DLG + ' form').validate({
                            rules : {
                                hostname : {
                                    required : true,
                                    fsDirServerHostCheck : HOST_NAME,
                                    notDuplicateFsDirSever : HOST_NAME
                               },
                               port : {
                                   required : true,
                                   fsDirServerPortNumericCheck : SSL_PORT,
                                   fsDirServerPortInRangeCheck : SSL_PORT
                               },
                               publickey : {
                                   required : true,
                                   fsDirServerCertCheck : KEY
                               }
                           }
                       });
                    }
                    /**
                     * @private
                     */
                    function validateDirectoryForm() {
                         $.validator.addMethod(
                                "fsDirNamingAttributeCheck", function(
                                        value, element, param) {
                                    errorInUID = true;
                                    $('#fs-settings-authn-example-text').show();
                                    return (value.toLowerCase().match("cn") || value.toLowerCase().match("uid"));
                                }, Localizer.getString('fs.settings.authn.addDirectory.invalid_naming_attribute'));
                         if(productConfigMembersData['settings.security.ldap.multirdn.disable'] === "true"){
                         $.validator.addMethod(
                                 "fsAddDirDisableMultiRdn", function(
                                         value, element, param) {
                                     errorInUID = true;
                                     var match = value.match(/\+/g);
                                     var count = match ? match.length : 0;
                                     return (count < 1);
                                 }, Localizer.getString('fs.settings.authn.addDirectory.disable_multirdn'));
                          }else {
                              var noOfRDNsSupported = 10;
                              if(productConfigMembersData['settings.security.ldap.no.of.rdns.supported'] !== undefined && 
                                  !isNaN(productConfigMembersData['settings.security.ldap.no.of.rdns.supported'])&&
                                  productConfigMembersData['settings.security.ldap.no.of.rdns.supported'] != 0){
                                      noOfRDNsSupported = productConfigMembersData['settings.security.ldap.no.of.rdns.supported'];  
                              }
                            $.validator.addMethod(
                                      "fsMaxSearchContextCheck", function(
                                              value, element, param) {
                                          errorInUID = true;
                                          var match = value.match(/\+/g);
                                          var count = match ? match.length : 0;
                                          return (count < noOfRDNsSupported);
                                      }, Localizer.getString('fs.settings.authn.addDirectory.max_search_context',[noOfRDNsSupported]));
                          }
                        directoryValidator = $(FORM).validate({
                            rules : {
                              username : {
                                  required : true
                              },
                              password : {
                                  required : true
                              }
                            },
                            ignore : ":hidden"
                        });

                        //create a validtor group for search-context controls so error message appears in one place
                        directoryValidator.groups.uid = 'search-context';
                        directoryValidator.groups.org = 'search-context';
                        directoryValidator.groups.top = 'search-context';

                        $(UID_TEXT).rules("add", {
                                            required : true,
                                            fsDirNamingAttributeCheck : UID_TEXT,
                                            messages : {
                                                required : Localizer.getString('fs.settings.authn.edit.baseDN_required_error')
                                            }
                         });
                         if(productConfigMembersData['settings.security.ldap.multirdn.disable'] === "true"){
                            $(ORG_TEXT).rules("add", {
                                required : true,
                                fsAddDirDisableMultiRdn : ORG_TEXT,
                                messages : {
                                    required : Localizer
                                            .getString('fs.settings.authn.edit.baseDN_required_error')
                                }
                            });
                        }else{
                            $(ORG_TEXT).rules("add", {
                                required : true,
                                fsMaxSearchContextCheck : ORG_TEXT,
                                messages : {
                                    required : Localizer
                                            .getString('fs.settings.authn.edit.baseDN_required_error')
                                }
                            });
                          }
                          $(TOP_TEXT).rules("add",{
                                            required : true,
                                            messages : {
                                                required : Localizer.getString('fs.settings.authn.edit.baseDN_required_error')
                                            }
                                        });
                    }
                    function localizeHelpText(){
                                $(HELP_TEXT).text("("+Localizer.getString('fs.settings.authn.addDirectory.help_example')+":"+
                                Localizer.getString('fs.settings.authn.addDirectory.help_field1')+": CN / UID "+
                                Localizer.getString('fs.settings.authn.addDirectory.help_field2')+": OU=example.com, OU=Users "+
                                Localizer.getString('fs.settings.authn.addDirectory.help_field3')+": DC=examplecorp, DC=net)");
                                
                    }
                    function isCredentialsTextMsgShow(){
                        if(UsersViewUtil.configs[UsersViewUtil.LDAP_CREDENTIAL_SAVE] !== null &&
                          UsersViewUtil.configs[UsersViewUtil.LDAP_CREDENTIAL_SAVE] !== undefined &&
                          UsersViewUtil.configs[UsersViewUtil.LDAP_CREDENTIAL_SAVE] === "true"){
                          $(CREDENTIALS_TEXT_MSG).hide();
                          }else{
                          $(CREDENTIALS_TEXT_MSG).show();
                         }
                    }
                    
                    this.init = function() {

                        dirFormStateView.init({
                            form : FORM,
                            routePattern : ROUTE_PREFIX + '.*',
                            autoTrack : true
                        });

                        // manually update formStateView on Search context controls
                        // because 3 textboxes are connected to 1 label
                        $(UID_TEXT).change(function() {
                            dirFormStateView.update(
                                    "fs-settings-authn-search-context-uid-text",
                                    Localizer.getString('fs.settings.authn.addDirectory.search_context_uid'), $(this).val(),
                                    "");
                        });
                        $(ORG_TEXT).change(function() {
                            dirFormStateView.update(
                                    "fs-settings-authn-search-context-org-text",
                                    Localizer.getString('fs.settings.authn.addDirectory.search_context_org'), $(this).val(),
                                    "");
                        });
                        $(TOP_TEXT).change(function() {
                            dirFormStateView.update(
                                    "fs-settings-authn-search-context-top-text",
                                    Localizer.getString('fs.settings.authn.addDirectory.search_context_top'), $(this).val(),
                                    "");
                        });

                        loadProductConfigData();
                        validateDirectoryForm();
                        validateServerForm();
                        addDirServerDlgTemplate = $(ADD_DIR_SERVER_DLG).detach().show();
                        Localizer.localizeDom(addDirServerDlgTemplate);

                        serverFormStateView.init({
                            form : $('form', addDirServerDlgTemplate),
                            routePattern : ROUTE_PREFIX + '.*',
                            autoTrack : true
                        });

                        initServersTable();
                        localizeHelpText();
                        resetDirParams();
                        dirFormStateView.reset();
                        resetServerParams();
                        serverFormStateView.reset();

                        presenter.loadSettingsEdit();

                        var protocols = presenter.getActiveProtocols();
                        $.each(protocols, function(index, protocol) {
                            $(TYPE_SELECT).append($('<option>', {
                                value : protocol.Id
                            }).text(protocol.name));
                        });
                        //apply select box styling
                        $(TYPE_SELECT).selectBox({autoWidth: false});

                        $(ADD_DIR_SERVER_BUTTON).on('click', function(ev) {
                            resetServerParams();
                            validateAddDirServerIP = true;
                            $(ADD_DIRSERVERS_HEADER, addDirServerDlgTemplate).show();
                            $(ADD_DIRSERVERS_FOOTER, addDirServerDlgTemplate).show();
                            $(EDIT_DIRSERVERS_HEADER, addDirServerDlgTemplate).hide();
                            $(EDIT_DIRSERVERS_FOOTER, addDirServerDlgTemplate).hide();
                            $(HOST_NAME, addDirServerDlgTemplate).val("");
                            $(SSL_PORT, addDirServerDlgTemplate).val("");
                            $(KEY, addDirServerDlgTemplate).val("");
                             onAddDirServer();
                             ev.preventDefault();
                        });

                        $(ADD_BUTTON_FOR_DIR).on('click', function(ev) {
                            addDirAgain = false;
                            onAddDirectory();
                            ev.preventDefault();
                        });

                        $(ADD_AGAIN_BUTTON_FOR_DIR).on('click', function(ev) {
                            addDirAgain = true;
                            onAddDirectory();
                            ev.preventDefault();
                        });

                        $(CANCEL_BUTTON_FOR_DIR).click(function() {
                            onCancelDirectory();
                        });
                        $(addDirServerDlgTemplate).on('click', '#edit-dir-server-ok', function (event,button) {
                            editDirServer(button);
                            event.preventDefault();
                        });
                        $(addDirServerDlgTemplate).on('click', '#fs-authn-add-dir-server-add', function (event,button) {
                             addAgainDirectory = false;
                             addDirServer(button);
                             event.preventDefault();
                        });
                        $(addDirServerDlgTemplate).on('click', '#fs-authn-add-dir-server-addAgain', function (event,button) {
                             addAgainDirectory = true;
                             addDirServer(button);
                             event.preventDefault();
                         });
                        isCredentialsTextMsgShow();
                       };
                    this.pause = function() {
                        // In case we navigate away before the apply completes
                        directoryValidator.resetForm();
                        serverValidator.resetForm();
                        dirFormStateView.reset();
                        serverFormStateView.reset();
                    };
                    this.resume = function() {
                        directoryValidator.resetForm();
                        serverValidator.resetForm();
                        dirFormStateView.reset();
                        serverFormStateView.reset();
                        $(DIR_NAME_TEXT).focus();
                        isCredentialsTextMsgShow();
                    };
                }

                return new AuthnAddDirectoryView();
            }());

            return AuthnAddDirectoryView;
        });
