// (C) Copyright 2020 Hewlett-Packard Enterprise Company, L.P.
define([ 'fs/model/settings/AuthNSettings',
         'fs/model/settings/AuthNProviders',
         'hp/services/authn',
         'hp/model/Session',
        'hp/core/EventDispatcher',
        'hp/core/Localizer' ],
        function (authnSettings, authnProviders, authnService, session,EventDispatcher, localizer) {
    "use strict";
    var AuthNPresenter = (function () {
        function AuthNPresenter() {
            var dispatcher = new EventDispatcher();
            var protocols = [ {
                "name" : "Active Directory",
                "Id" : "AD"
            }, {
                "name" : "OpenLDAP",
                "Id" : "LDAP"
            } ];
            var getFullConfigs = false;
            var callsToMake = 0;
            var callsMade = 0;

            function checkGetCallsStatus() {
                callsMade++;
                if (callsToMake <= callsMade) {
                    authnProviders.sortProviderConfigsByName();
                    dispatcher.fire("onGetAllProvidersComplete");
                    callsToMake = 0;
                    callsMade = 0;
                }
            }

            function onGetAuthServiceSuccess(authServiceDto) {
                authnProviders.addProviderConfig(authServiceDto);
                checkGetCallsStatus();
            }

            function onGetAuthServiceError(errorInfo) {
                checkGetCallsStatus();
                var failureMessage = localizer.getString('fs.settings.authn.failed_get_provider_info');
                dispatcher.fire('getGlobalSettingsError', {
                    "errorInfo" : errorInfo,
                    "failureMessage" : failureMessage
                });
            }

            function getProviderConfig(providerUri) {
                authnService.getResource(providerUri, {
                    success : onGetAuthServiceSuccess,
                    error : onGetAuthServiceError
                });
            }

            function onGetGlobalSettingsSuccess(globalSettingsDto) {
                var allowLocalLoginDto = {
                    "allowLocalLogin" : globalSettingsDto.allowLocalLogin
                };
                authnSettings.setAllowLocalLogin(allowLocalLoginDto);
                authnSettings.setDefaultProvider(globalSettingsDto.defaultLoginDomain);
                authnSettings.setProviderInfos(globalSettingsDto.configuredLoginDomains);

                dispatcher.fire('getGlobalSettingsComplete');
                if (getFullConfigs) {
                    //get the total number of providers available to find out when the page is
                    //done painting
                    callsToMake = globalSettingsDto.configuredLoginDomains.length;
                    if(callsToMake==0)
                    {
                        dispatcher.fire("onGetAllProvidersComplete");
                    }
                    $.each(globalSettingsDto.configuredLoginDomains, function(i, providerInfo) {
                        getProviderConfig(providerInfo.uri);
                    });
                }
            }

            function onGetGlobalSettingsError(errorInfo) {
                authnSettings.setAllowLocalLogin(null);
                authnSettings.setDefaultProvider(null);
                authnSettings.setProviderInfos(null);
                var failureMessage = localizer.getString('fs.settings.authn.failed_get_global_settings');
                dispatcher.fire('getGlobalSettingsError', {
                    "errorInfo" : errorInfo,
                    "failureMessage" : failureMessage
                });
            }

            function loadAuthenticationSettings() {
                authnService.getGlobalSettings({
                    success : onGetGlobalSettingsSuccess,
                    error : onGetGlobalSettingsError
                });
            }

            function getData() {
                authnSettings.clear();
                authnProviders.clear();
                callsToMake = 0;
                callsMade = 0;
                loadAuthenticationSettings();
            }

            function onSaveSettingsSuccess(handlers) {
                loadAuthenticationSettings();
                handlers.success();
            }

            function onSaveSettingsError(errorInfo, handlers) {
                handlers.error(errorInfo);
            }


            function setGlobalSettings(dfd) {
                authnService.setGlobalSettings(authnSettings.getAllowLocalLogin().allowLocalLogin, authnSettings
                        .getDefaultProvider(), {
                    success : dfd.resolve,
                    error : dfd.reject
                });
                return dfd.promise();
            }

            this.saveSettings = function(handlers) {
               var dfd = $.Deferred();
             //   callsToMake = removeNullPlaceholders(authnProviders.getProviderConfigs()).length;
            //    callsToMake += removeNullPlaceholders(authnProviders.getDeletedProviderConfigs()).length;
                //pass deferred object and check returned promise if the call was successful
                //this is to first Save the global settings. If that is successful then save the rest of
                //of the provider configurations
                setGlobalSettings(dfd).done(function() {
                    
                        onSaveSettingsSuccess(handlers);
                 
                }).fail(function(errors) {

                    onSaveSettingsError({
                        "errorInfo" : errors,
                        "failureMessage" : localizer.getString('fs.settings.authn.auth_settings_error')
                    }, handlers);
                });
            };

            this.loadSettingsOverview = function() {
                getFullConfigs = false;
                getData();
            };

            this.loadSettingsEdit = function() {
                getFullConfigs = true;
                getData();
            };

            this.on = function(eventName, callback) {
                dispatcher.on(eventName, callback);
            };

            this.off = function(eventName, callback) {
                dispatcher.off(eventName, callback);
            };

            this.getAllowLocalLogin = function() {
                return authnSettings.getAllowLocalLogin();
            };

            this.setAllowLocalLogin = function(value) {
                var allowLocalLoginDto = {
                    "allowLocalLogin" : value
                };
                authnSettings.setAllowLocalLogin(allowLocalLoginDto);
            };

            this.getProviderFullConfigById = function(loginDomain) {
                return authnProviders.getProviderConfigById(loginDomain);
            };

            this.getIndexByConfigId = function(loginDomain) {
                return authnProviders.getIndexByConfigId(loginDomain);
            };

            this.getProviderConfigByIndex = function(index) {
                return authnProviders.getProviderConfigByIndex(index);
            };

            this.getDefaultProvider = function() {
                return authnSettings.getDefaultProvider();
            };

            this.getActiveProtocols = function() {
                return protocols;
            };

            this.setDefaultProviderById = function(loginDomain) {
                if (loginDomain === "0") {
                    authnSettings.setDefaultProvider({
                        "type" : "LoginDomainConfigInfoDto",
                        "name" : "LOCAL",
                        "uri" : "",
                        "loginDomain" : "0"
                    });
                    return;
                }
                var providerInfo = authnSettings.getProviderInfoById(loginDomain);
                if (providerInfo !== null) {
                    authnSettings.setDefaultProvider(providerInfo);
                } else {
                    var errorInfo = {
                        "errorMessage" : localizer.getString('fs.settings.authn.failed_set_default_provider'),
                        "resolution" : localizer.getString('fs.settings.authn.refresh_and_verify_provider')
                    };
                    dispatcher.fire('setAuthenticationSettingsError', {
                        "errorInfo" : errorInfo,
                        "failureMessage" : localizer.getString('fs.settings.authn.auth_settings_error')
                    });
                }
            };

            this.getProviderInfos = function() {
                return authnSettings.getProviderInfos();
            };

            this.getProviderInfosWithLocal = function() {
                // Copy the original array.
                var providerInfos = this.getProviderInfos().slice(0);
                // Add the local provider to it for use in lists where
                // local is desired.
                providerInfos.splice(0, 0, {
                    "name" : "LOCAL",
                    "uri" : "",
                    "loginDomain" : "0"
                });
                return providerInfos;
            };
            
            this.setProviderInfos = function(value) {
                authnSettings.setProviderInfos(value);
            };

            this.getAllowLocalLoginDisplayValue = function() {
                var allowLocalLoginDto = authnSettings.getAllowLocalLogin();
                var displayValue = localizer.getString('fs.settings.authn.enabled');
                if (!allowLocalLoginDto.allowLocalLogin) {
                    displayValue = localizer.getString('fs.settings.authn.disabled');
                }
                return displayValue;
            };

            this.getDefaultProviderDisplayValue = function() {
                var defaultProviderInfo = authnSettings.getDefaultProvider();
                var displayValue = "";
                if(defaultProviderInfo) {
                    if (defaultProviderInfo.name) {
                        if (defaultProviderInfo.name.toLowerCase() === "local") {
                            displayValue = localizer.getString('fs.settings.authn.local');
                        } else {
                            displayValue = defaultProviderInfo.name;
                        }
                    }
                }
                return displayValue;
            };

            this.getProviderInfosDisplayValues = function() {
                var providerInfos = authnSettings.getProviderInfos();
                var displayValues = [];
                var providerConfigured = false;
                if (providerInfos !== null && providerInfos.length > 0) {
                    providerConfigured = true;
                    for (var i = 0; i < providerInfos.length; i++) {
                        if (i < 2) {
                            displayValues.push(providerInfos[i].name);
                        } else {
                            var additionalProviderCount = providerInfos.length - 2;
                            displayValues.push(localizer.getString('fs.settings.authn.plus_more', [ additionalProviderCount ]));
                            break;
                        }
                    }
                }
                return {
                    "providerConfigured" : providerConfigured,
                    "displayValues" : displayValues
                };
            };

            this.setProviderConfigs = function(configs) {
                authnProviders.setProviderConfigs(configs);
            };

            this.getProviderConfigs = function() {
                return authnProviders.getProviderConfigs();
            };

            this.addProviderConfig = function(config) {
                authnProviders.addProviderConfig(config);
            };
            /**
             * Add Group to Role Mappings
             *
             * @param {string}
             *            loginDomain.
             * @param {string}
             *            group.
             * @param {string}
             *            roles.*            
             * @param {string}
             *            userName.
             * @param {string}
             *            password.
             * @param {{success:function():void,
             *            error:function(string):void}} handlers
             *            Function to call on success or error; the
             *            parameter to the error handler is an error
             *            message.
             */
            this.addGroupToRoleMappings = function(loginDomain, group,roles, userName, password, handlers) {
                authnService.addGroupToRoleMappings(loginDomain, group,roles, userName, password,
                         {
                            success : function() {
                                handlers.success();
                            },
                            error : function(errorInfo) {
                                handlers.error(errorInfo);
                            }
                        });
            };
            /**
             * Create Provider Config
             *
             * @param {Dto}
             *              directoryConfigDto
             * @param {{success:function():void,
             *            error:function(string):void}} handlers
             *            Function to call on success or error; the
             *            parameter to the error handler is an error
             *            message.
             */
            this.addDirectory = function(directoryConfig, handlers) {
                authnService.addDirectory(directoryConfig,
                         {
                            success : function() {
                                handlers.success();
                            },
                            error : function(error) {
                                handlers.error(error);
                            }
                        });
            };

            /**
             * Validate the directory server before adding
             *
             * @param {Dto}
             *              serverConfig
             * @param {{success:function():void,
             *            error:function(string):void}} handlers
             *            Function to call on success or error; the
             *            parameter to the error handler is an error
             *            message.
             */
            this.validateDirectoryServer = function(serverConfig, handlers) {
                authnService.validateDirectoryServer(serverConfig,
                         {
                            success : function() {
                                handlers.success();
                            },
                            error : function(error) {
                                handlers.error(error);
                            }
                        });
            };
           
            /**
              * Edit the Directory
              * @param{String}
              *         URI to the edit directory 
              * @param {Object}
              *        directoryConfigDto
              * @param {{success:function():void,
              *            error:function(string):void}} handlers
              *            Function to call on success or error; the
              *            parameter to the error handler is an error
              *            message.
              */
             this.updateDirectory = function(uri,directoryConfigDto, handlers) {
                    authnService.updateDirectory(uri,directoryConfigDto,handlers);
               }; 
              /**
               * Delete the directory
               * @param {String}
               *         URI to the delete directory    
               * @param {{success:function():void,
               *        error:function(Object):void}} handlers
               *        Function to call on success or error; the
               *        parameter to the error handler is an error
               *        object.
              */
              this.deleteProviderConfig =  function(uri,handlers){
                  authnService.deleteProviderConfig(uri,handlers);
              };
               
        }

        return new AuthNPresenter();

    }());

    return AuthNPresenter;
});
