// (C) Copyright 2020 Hewlett-Packard Enterprise Company, L.P.
define(['fs/presenter/settings/CertificatePresenter',
        'hp/core/Localizer',
        'hp/core/Router',
        'fs/presenter/settings/PublicKeyPresenter',
        'fs/presenter/settings/AuthNPresenter',
        'fs/presenter/settings/SettingsPresenter',
        'fs/view/common/CommonDisplayView',
        'hp/core/EventDispatcher',
        'hp/view/NotificationsView',
        'jquery',
        'lib/jquery.dateFormat',
        'hp/lib/jquery.hpStackedPanels'],
function(certificatePresenter, localizer, router, publickeyPresenter,authnPresenter, settingsPresenter, commonDisplayView, dispatcher,NotificationsView) { "use strict";

    var SecurityMoreView = (function() {

        var CLASS_PREFIX = '.fs-settings-security';

        var ID_PREFIX = CLASS_PREFIX.replace('.', '#'),
            CERTIFICATE_PREFIX = ID_PREFIX + '-certificate',
            COMMON_NAME = CERTIFICATE_PREFIX + '-common-name',
            ISSUED_BY = CERTIFICATE_PREFIX + '-issued-by',
            VALID_FROM = CERTIFICATE_PREFIX + '-valid-from',
            VALID_UNTIL = CERTIFICATE_PREFIX + '-valid-until',
            SERIAL_NUMBER = CERTIFICATE_PREFIX + '-serial-number',
            VERSION = CERTIFICATE_PREFIX + '-version',
            MD5_FINGERPRINT = CERTIFICATE_PREFIX + '-md5-fingerprint',
            SHA1_FINGERPRINT = CERTIFICATE_PREFIX + '-sha1-fingerprint',
            COUNTRY = CERTIFICATE_PREFIX + '-country',
            STATE = CERTIFICATE_PREFIX + '-state',
            LOCALITY = CERTIFICATE_PREFIX + '-locality',
            ORG = CERTIFICATE_PREFIX + '-org',
            OU = CERTIFICATE_PREFIX + '-ou',
            ALT_NAME = CERTIFICATE_PREFIX + '-alt-name',
            CONTACT = CERTIFICATE_PREFIX + '-contact',
            EMAIL = CERTIFICATE_PREFIX + '-email',
            SURNAME = CERTIFICATE_PREFIX + '-surname',
            GIVEN_NAME = CERTIFICATE_PREFIX + '-given-name',
            INITIALS = CERTIFICATE_PREFIX + '-initials',
            DN = CERTIFICATE_PREFIX + '-dn',
            UNSTRUCTURED_NAME = CERTIFICATE_PREFIX + '-unstructured-name',
            PUBLICKEY_PREFIX = ID_PREFIX + '-publickey',
            DISPLAY = PUBLICKEY_PREFIX + '-display',
            EXPIRES_IN = CERTIFICATE_PREFIX + '-expires-in',
            ALLOW_LOCAL_LOGIN_VALUE_CONATINER = '#cic-settings-authn-allow-local',
            DEFAULT_PROVIDER_VALUE_CONTAINER = '#cic-settings-authn-default-provider',
            PROVIDER_CONFIG_PROTOCOL ='#fs-settings-authn-ptotocol-text',
            DIRECTORY_NAME_TXT = "#fs-settings-authn-directory-name-text",
            TEMPLATE = "#fs-settings-security-more-display-directories",
            LIST = '#fs-settings-security-more-directories',
            PROVIDER_CONFIG_UID ="#fs-settings-authn-uid-text",
            PROVIDER_CONFIG_BASEDN = "#fs-settings-authn-basedn-text" ,
            PROVIDER_CONFIG_DIRSERVERS_TEMPLATE = ".fs-settings-authn-dirservers-template",
            PROVIDER_CONFIG_DIRSERVERS_TEXT = "#fs-settings-authn-dirservers-text",
            NO_DIRECTORIES = "#fs-settings-security-authn-no-directories",
            FIRMWAREBUNDLE_UPDATE_FIELD = '#fs-settings-security-firmwarebundle-update',
            SECURITY_FIRMWAREBUNDLE_UPDATE_OPTION = "SECURITY_FIRMWAREBUNDLE_UPDATE_OPTION",
            SECURITY_FIRMWAREBUNDLE_PANEL_ITEM = "#fs-settings-security-firmwarebundle";
        var PANELS = ID_PREFIX + '-panels',
            PANEL_SELECTOR = '#hp-settings-panel-selector',
            ROUTE_PREFIX = '/settings/show/security/(authentication|directories|certificate|publickey|firmwarebundle)',
            UNSET = 'hp-unset',
            ADD_NOTIFICATION = 'addNotification';
        var serverTemplate;
        /**
         * Constructor
         */
        function SecurityMoreView() {
            var notifications = new NotificationsView();
            // Displays an error in the Notifications view.  This is done by posting
            // a jQuery event that bubbles up the element stack to the SettingsView,
            // which owns the notifications area.
            function showError(error) {
                $(PANELS).trigger(ADD_NOTIFICATION, {
                    summary: error.errorMessage,
                    details: error.resolution,
                    status: 'error'
                }, true);
            }

            // Show the contents of a field, with handling of "not set".
            function setField(field, value) {
                if (value) {
                    $(field).text(value).removeClass(UNSET);
                } else {
                    $(field).html('<span class="hp-help">' + localizer.getString('core.common.notset') + '</span>');
                }
            }

            // Display the certificate data (called when it is received from the server).
            function showCertificateData(certObject) {
                setField(COMMON_NAME, certObject.commonName);
                setField(ISSUED_BY, certObject.issuer);
                var valid_from = null;
                if (certObject.validFrom) {
                    valid_from = $.format.date(Date.parseISOString(certObject.validFrom), 'yyyy-MM-dd') + "T" +
                        $.format.date(Date.parseISOString(certObject.validFrom), 'HH:mm:ss')+
                        $.format.date(Date.parseISOString(certObject.validFrom), 't');
                }
                setField(VALID_FROM, valid_from);
                var valid_until = null;
                if (certObject.validUntil) {
                    valid_until = $.format.date(Date.parseISOString(certObject.validUntil), 'yyyy-MM-dd') + "T" +
                        $.format.date(Date.parseISOString(certObject.validUntil), 'HH:mm:ss')+
                        $.format.date(Date.parseISOString(certObject.validUntil), 't');
                }
                setField(VALID_UNTIL, valid_until);
                var expires_in = certObject.expiresInDays;
                if (expires_in < 31) {
                    $(EXPIRES_IN).html('<span class="hp-warning">' + 
                            localizer.getString('fs.settings.security.overview.expires_in', [ expires_in ]) + 
                    '</span>').removeClass(UNSET);
                } else if (expires_in < 184) {
                    $(EXPIRES_IN).html('<span class="hp-help">' + 
                            localizer.getString('fs.settings.security.overview.expires_in', [ expires_in ]) + 
                    '</span>').removeClass(UNSET);
                }
                setField(SERIAL_NUMBER, certObject.serialNumber);
                setField(VERSION, certObject.version);
                setField(MD5_FINGERPRINT, certObject.md5Fingerprint);
                setField(SHA1_FINGERPRINT, certObject.sha1Fingerprint);
                setField(COUNTRY, certObject.country);
                setField(STATE, certObject.state);
                setField(LOCALITY, certObject.locality);
                setField(ORG, certObject.organization);
                setField(OU, certObject.organizationalUnit);
                setField(ALT_NAME, certObject.alternativeName);
                setField(CONTACT, certObject.contactPerson);
                setField(EMAIL, certObject.email);
                setField(SURNAME, certObject.surname);
                setField(GIVEN_NAME, certObject.givenName);
                setField(INITIALS, certObject.initials);
                setField(DN, certObject.dnQualifier);
                setField(UNSTRUCTURED_NAME, certObject.unstructuredName);
            }

            // Retrieve the certificate data from the server.
            function getCertificateData() {
                certificatePresenter.getCertificate({
                    success: showCertificateData,
                    error: showError
                });
            }

            function changeLocation(location) {
                $(PANELS).hpStackedPanels('setPanelByLocation', '#' + location);
            }

            function onGetPublicKeySuccess(data){
                /*Adding a check to see if the line separators are truncated by the some browsers.
                If truncated adding it.*/
                //Adding the check to both Public keys currently provided by HP.
                var begin_index = data.indexOf('Version');
                if(begin_index != -1){
                    if(data[begin_index-1] != '\n'){
                        data = data.replace('Version: GnuPG v1.4.10 (MingW32)','\r\nVersion: GnuPG v1.4.10 (MingW32)\r\n');
                        data = data.replace('Version: GnuPG v1.4.0 (MingW32)','\r\nVersion: GnuPG v1.4.0 (MingW32)\r\n');
                    }
                }
                var end_index = data.indexOf('-----END PGP PUBLIC KEY BLOCK-----');
                if(end_index != -1){
                    if(data[end_index-1] != '\n'){
                        data = data.replace('-----END PGP PUBLIC KEY BLOCK-----','\r\n-----END PGP PUBLIC KEY BLOCK-----');
                    }
                }
                var index = data.indexOf('=aphN');
                if(index != -1){
                    if(data[index-1]!= '\n'){
                        data = data.replace('=aphN','\r\n=aphN');
                    }
                }
                else{
                    index = data.indexOf('=+cX+');
                    if(index != -1){
                        if(data[index-1]!= '\n'){
                            data = data.replace('=+cX+ ','\r\n=+cX+');
                        }
                    }
                }
                var key_window = window.open("", "_blank", "scrollbars=1");
                key_window.document.write("<pre>"+data+"</pre>");
            }

            /*
             * Error message displayed in NotificationView
             *
             */
            function onGetPublicKeyError(errorInfo){
                var errorDisplayingPublicKey = {
                    sourceName: localizer.getString('fs.settings.security.panel.hp_public_key'),
                    summary : errorInfo.message,
                    status : "error"
                };
                notifications.add(errorDisplayingPublicKey, false, true, true);
            }

          

            function getPublicKey(){
                publickeyPresenter.getPublicKey();
            }
            //Retrieve authentication data from server
            function onGetGlobalSettingsSuccess() {
                $(ALLOW_LOCAL_LOGIN_VALUE_CONATINER).text(authnPresenter.getAllowLocalLoginDisplayValue());
                $(DEFAULT_PROVIDER_VALUE_CONTAINER).text(authnPresenter.getDefaultProviderDisplayValue());
               var providerInfos = authnPresenter.getProviderInfos();
               if (providerInfos !== null && providerInfos.length === 0) {
                   $(NO_DIRECTORIES).show(); 
                   }else{
                   $(NO_DIRECTORIES).hide();
                   }
               }
            
            function onGetGlobalSettingsError(errorInfo) {
                 var failureMessage = localizer.getString('fs.settings.authn.failed_get_global_settings');
                 dispatcher.fire('getGlobalSettingsError', {
                    "errorInfo" : errorInfo,
                    "failureMessage" : failureMessage
                 });
            }
            function displayDirectoryServers(server , service){
                    var list = $(".hp-form-input", service);
                    var item = serverTemplate.clone();
                    $(PROVIDER_CONFIG_DIRSERVERS_TEXT, item).append(server);
                    $('table thead', list).append(item);
                    $('table',list).show();
                    
            }
            
            function getAllDirectoriesInfo(authServiceConfig) {
                var serviceNameText = "";
                var protocolText = "";
                var service;
                var topText = "";
                var userNameFieldText = "";
                var orgText = "";
                var servers = [];
                if (authServiceConfig) {
                    serviceNameText = authServiceConfig.name;
                    protocolText = authServiceConfig.authProtocol;
                    topText = authServiceConfig.top;
                    userNameFieldText = authServiceConfig.userNameField;
                    orgText = authServiceConfig.org;
                    servers = authServiceConfig.directoryServers;
                }
                service = $(TEMPLATE).clone();
                //set values on each control
               if(protocolText==='AD'){
                   protocolText = localizer.getString('fs.settings.security.more.authn.active_directory');
               }else{
                   protocolText = localizer.getString('fs.settings.security.more.authn.open_ldap');
               }
                $(PROVIDER_CONFIG_PROTOCOL,service).text(protocolText);
                $(DIRECTORY_NAME_TXT,service).text(serviceNameText);
                $(PROVIDER_CONFIG_UID,service).text(userNameFieldText);
                $(PROVIDER_CONFIG_BASEDN,service).text(orgText+","+topText);
                serverTemplate = $(PROVIDER_CONFIG_DIRSERVERS_TEMPLATE, service)
                    .removeClass(PROVIDER_CONFIG_DIRSERVERS_TEMPLATE).remove().show();
                if (servers.length > 0) {
                 $.each(servers, function(index, server) {
                     displayDirectoryServers(server.directoryServerIpAddress, service);
                    });
                }
                service.show();
                $(LIST).append(service);
                $(LIST).append("<br/>");
             }
              //Retrieve directories data from server
            function getDirectoriesData(){
                var authConfigs = authnPresenter.getProviderConfigs();
                $.each(authConfigs, function(index, config) {
                    getAllDirectoriesInfo(config);
                });
            }

            function onSettingSuccess(setting){
                if(setting.value === "http"){
                    $(FIRMWAREBUNDLE_UPDATE_FIELD).text(localizer.getString('fs.settings.security.firmwarebundle.http'));
                }
                if(setting.value === "https"){
                    $(FIRMWAREBUNDLE_UPDATE_FIELD).text(localizer.getString('fs.settings.security.firmwarebundle.https'));
                }
            }

            function onGetSettingError(errorInfo){
                var setting = {
                          "type":"Setting",
                          "name":SECURITY_FIRMWAREBUNDLE_UPDATE_OPTION,
                          "value":"http",
                          "uri":"/rest/global-settings/"+SECURITY_FIRMWAREBUNDLE_UPDATE_OPTION,
                          "state":null,
                          "description":null,
                          "status":null,
                          "category":null,
                          "created":null,
                          "modified":null,
                          "eTag":null
                          };
                  settingsPresenter.setSetting(setting);
            }

            function getProductConfigSuccess(productConfigs){
                if (productConfigs["settings.security.firmwarebundles.show"] === "true"){
                    settingsPresenter.getSetting(SECURITY_FIRMWAREBUNDLE_UPDATE_OPTION);
                    $(SECURITY_FIRMWAREBUNDLE_PANEL_ITEM).show();
                }else{
                    $(SECURITY_FIRMWAREBUNDLE_PANEL_ITEM).detach();
                }
            }

            function getProductConfigError(errorInfo){
                $(SECURITY_FIRMWAREBUNDLE_PANEL_ITEM).detach();
            }

            /*
             * Register Events with Presenter layer
             */
            function registerEvents(){
                publickeyPresenter.on('getPublicKeySuccess',onGetPublicKeySuccess);
                publickeyPresenter.on('getPublicKeyError',onGetPublicKeyError);
                authnPresenter.on("getGlobalSettingsComplete", onGetGlobalSettingsSuccess);
                authnPresenter.on("getGlobalSettingsError", onGetGlobalSettingsError);
                authnPresenter.on("onGetAllProvidersComplete", getDirectoriesData);
                settingsPresenter.on("onGetSettingSuccess",onSettingSuccess);
                settingsPresenter.on("onGetSettingError", onGetSettingError);
                settingsPresenter.on("onSetSettingSuccess",onSettingSuccess);
                settingsPresenter.on('getProductConfigSuccess', getProductConfigSuccess);
                settingsPresenter.on('getProductConfigError', getProductConfigError);
            }

            /*
             * Un-Register Events
             */
            function removeEvents(){
                publickeyPresenter.off('getPublicKeySuccess',onGetPublicKeySuccess);
                publickeyPresenter.off('getPublicKeyError',onGetPublicKeyError);
                authnPresenter.off("getGlobalSettingsComplete", onGetGlobalSettingsSuccess);
                authnPresenter.off("getGlobalSettingsError", onGetGlobalSettingsError);
                authnPresenter.off("onGetAllProvidersComplete", getDirectoriesData);
                settingsPresenter.off("onGetSettingSuccess",onSettingSuccess);
                settingsPresenter.off("onGetSettingError", onGetSettingError);
                settingsPresenter.off("onSetSettingSuccess",onSettingSuccess);
                settingsPresenter.off('getProductConfigSuccess', getProductConfigSuccess);
                settingsPresenter.off('getProductConfigError', getProductConfigError);

            }
            this.init = function() {
                $(DISPLAY).attr('title', localizer.getString('fs.settings.security.publickey.key_message'));
                $(PANELS).hpStackedPanels({
                    panelSelector : PANEL_SELECTOR
                });
                router.watch('settings show security section', ROUTE_PREFIX + '.*',
                        {parent: ROUTE_PREFIX, change: changeLocation});
                getCertificateData();
                $(DISPLAY).on('click', function(){
                    getPublicKey();
                });
                registerEvents();
                authnPresenter.loadSettingsEdit();
                settingsPresenter.getProductConfig();
                commonDisplayView.manageDisplayInOverviewDropdown();
            };

            this.resume = function() {
                $(PANELS).hpStackedPanels('resume');
                $(LIST).empty();
                getCertificateData();
                registerEvents();
                authnPresenter.loadSettingsEdit();
                settingsPresenter.getProductConfig();
                commonDisplayView.manageDisplayInOverviewDropdown();
            };

            this.pause=function(){
                $(PANELS).hpStackedPanels('pause');
                removeEvents();
            };

        }

        return new SecurityMoreView();

    }());

    return SecurityMoreView;
});
