// (C) Copyright 2020 Hewlett-Packard Enterprise Company, L.P.
define(
    [ 'fs/presenter/settings/CertificatePresenter',
      'hp/view/FormStateView',
      'hp/view/DialogView',
      'hp/core/Notifications',
      'hp/core/Localizer',
      'text!fsPages/settings/certificate/importCertificate.html',
      'hp/core/Router',
      'hp/model/Session',
      'jquery',
      'hp/lib/jquery.hpCollapsible',
      'lib/jquery.validate' ],
function(presenter, FormStateView, DialogView, notifications, localizer, importCertHtml, router, session) { "use strict";

      var CertificateImportView = (function() {

          var FORM = '#cic-signed-import-form',
              BASE64_TEXT = '#cic-import-base64-text',
              OK = "#cic-import-base64-ok",
              CANCEL = '#cic-import-base64-cancel',
              DISABLED = 'disabled',
              SPLASH_DIALOG = '#cic-import-splash-dialog',
              SPLASH_PROGRESS = '#cic-import-splash-progress',
              SPLASH_ESTIMATE = '#cic-import-splash-estimate',
              IMPORT_COLLAPSIBLE = "#cic-import-collapsible",
              LOGGED_IN_MSG = '#cic-import-logged-in-msg';

          var RELOAD_TIMEOUT = 15000;
          // Total timeout / length of progress bar
          var RESTART_TIMEOUT = 30000; // msec

        /**
         * Constructor
         */
        function CertificateImportView() {
            var formStateView = new FormStateView();

            // Splash dialog timer
            var splashTimer;

            // Display an error in the dialog Notifications view.
            function displayDialogNotification(action, source, message, details) {
                var notif = {
                    summary : action,
                    sourceName : source,
                    uri : 'importcertificate-error' + (new Date()).getTime(),
                    status : 'error',
                    details : message + '\n' + details
                    };
                    formStateView.setMessage(notif);
                    notifications.add(notif, true);
            }

            /**
             * @private Formats error information from a REST request
             * @param errorInfo {object} Rest request error information
             * @returns {String} Formatted error information to display
             */
            function formatNotificationDetails(errorInfo) {
                var failureNotificationDetails = "";
                var resolution = "";
                var supportDumpLink = '<a href=\'#/settings/support/createSupportDump\'>' +
                            localizer.getString('fs.settings.certificate.selfsigned.error.support_dump_link') + '</a>';
                var supportDumpLinkMsg =
                             localizer.getString('fs.settings.certificate.selfsigned.error.support_dump_link_message',
                             [supportDumpLink]);
                // error from the task tracker in the form of an array
                if ($.isArray(errorInfo))
                {
                    for(var i=0; i < errorInfo.length; i++) {
                        var serverError = errorInfo[i];
                            resolution = serverError.recommendedActions ? '</br>' +
                                    serverError.recommendedActions.join(' ') : '';
                            failureNotificationDetails += serverError.message + resolution + '</br>';
                        }
                }
                // error directly from the REST request
                else
                {
                    var message = (errorInfo.message === null) ? '' : errorInfo.message;
                    resolution = errorInfo.recommendedActions ? '</br>' + errorInfo.recommendedActions.join(' ') : '';
                    failureNotificationDetails = message + resolution + '</br>';
                }
                failureNotificationDetails += '</br>' + supportDumpLinkMsg;

                return failureNotificationDetails;
            }

            /**
             * Dismiss the progress dialog box.
             */
            function dismissDialog() {
                if(splashTimer) {
                    clearTimeout(splashTimer);
                    splashTimer = null;
                }
                $(SPLASH_DIALOG).dialog('close');
            }

            function onImportCertError(errorInfo) {
                dismissDialog();
                var action = localizer.getString('fs.settings.certificate.signedimport.import_action');
                var source = localizer.getString('fs.settings.certificate.signedimport.certificate');
                var applyErrorMsg = localizer.getString('fs.settings.certificate.signedimport.error.unknown.msg');
                var failureNotificationDetails = formatNotificationDetails(errorInfo);
                displayDialogNotification(action, source, applyErrorMsg, failureNotificationDetails);
            }

            function onImportCertSuccess() {
                var notif = {
                    summary : localizer.getString('fs.settings.certificate.signedimport.import_action'),
                    sourceName : localizer.getString('fs.settings.certificate.signedimport.certificate'),
                    uri : 'importcertificate-success' + (new Date()).getTime(),
                    status : 'ok',
                    details : localizer.getString('fs.settings.certificate.signedimport.import_success')
                };
                notifications.add(notif, true);
                formStateView.setMessage(notif);

                setTimeout( function() {
                    dismissDialog();
                    var notPersistent = false;
                    session.setProperty("navToSettingsOverview","true",notPersistent);
                    router.reload();
                }, RELOAD_TIMEOUT );
            }

            /**
             * When the importSignedCertificate call returns
             * success, display the splash dialog.
             */
            function onImportCertRunning(timeout) {
                $(SPLASH_DIALOG).dialog('open');

                // update progress
                $(SPLASH_PROGRESS).hpProgressBar(0);
                var done = 0;
                var remaining = 0;
                $(SPLASH_ESTIMATE).text(localizer.getString('fs.settings.certificate.selfsigned.dialog.remaining',
                        [timeout/1000]));
                splashTimer = setInterval(function() {
                    done += 1000;
                    remaining = timeout-done;
                    if( remaining < 0 )
                    {
                        remaining = 0 ;
                    }
                    $(SPLASH_ESTIMATE).text(localizer.getString('fs.settings.certificate.selfsigned.dialog.remaining',
                            [remaining/1000]));
                    $(SPLASH_PROGRESS).hpProgressBar((done * 100) / timeout);
                }, 1000);
            }

            /**
             * Display the list of logged in users
             * @returns number of logged in users
             */
            function updateOtherUsersLoggedIn() {
                var list = presenter.getOtherUsersLoggedInList();
                var count = list.length;
                for ( var i = 0; i < list.length; i++) {
                    $('.hp-dependencies', FORM).append('<li>' + list[i] + '</li>');
                }
                if (count > 1) {
                    $(LOGGED_IN_MSG).text(localizer.getString(
                                  'fs.settings.certificate.selfsigned.dialog.usersLoggedIn', [ count ]));
                } else if (count == 1) {
                    $(LOGGED_IN_MSG).text(localizer.getString(
                                  'fs.settings.certificate.selfsigned.dialog.oneUserLoggedIn'));
                } else if (count == 0) {
                    $(LOGGED_IN_MSG).text('');
                }
                return count;
              }

            /**
             * Handler to get the list of logged in users
             */
            function onUsersLoggedInSuccess() {
                updateOtherUsersLoggedIn();
            }

            /**
             * If we have an error retrieving the logged in list, don't display
             * the logged in message
             * @param errorInfo
             */
            function onUsersLoggedInError(errorInfo){
                $(LOGGED_IN_MSG).text('');
            }

            /**
             * Register events
             */
            function registerEvents() {
                presenter.on("usersLoggedInSuccess", onUsersLoggedInSuccess);
                presenter.on("usersLoggedInError", onUsersLoggedInError);
            }

            /**
             * Unregister events
             */
            function removeEvents() {
                presenter.off("usersLoggedInSuccess", onUsersLoggedInSuccess);
                presenter.off("usersLoggedInError", onUsersLoggedInError);
            }

          /**
           * Create the certificate
           */
          var importCert = function() {
              //get the base64 encoded data from the text area
              var base64Text = $(BASE64_TEXT).val();
              var certObject = {
                  base64Data : base64Text
              };
              var unitTest = false;
              onImportCertRunning(RESTART_TIMEOUT);
              presenter.importSignedCertificate(certObject, unitTest, {
                  success : onImportCertSuccess,
                  error : onImportCertError
              });
          };

          /**
           * @public
           */
          this.init = function() {

              registerEvents();

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

              $(BASE64_TEXT).attr('placeholder', localizer.getString('fs.settings.certificate.signedimport.import_paste'));

              // reset and then obtain list of logged in users for the warning dialog
              presenter.init();
              presenter.usersLoggedIn();

              $(IMPORT_COLLAPSIBLE).hpCollapsible();

              // Handlers for the buttons.
              $(OK).click(function(ev) {
                  importCert();
              });

              $(CANCEL).click(function(ev) {
                  $(BASE64_TEXT).val("");
                  formStateView.reset();
              });

              $(BASE64_TEXT).bind("input paste propertychange change", function (e) {
                  if ($(BASE64_TEXT).val()) {
                      $(OK).prop(DISABLED, false);
                  } else {
                      $(OK).prop(DISABLED, true);
                  }
              });

              $(SPLASH_DIALOG).dialog({
                  autoOpen : false,
                  modal : true,
                  position : "center",
                  draggable : false,
                  resizable : false,
                  show : 'fade',
                  dialogClass : 'hp-splash-dialog',
                  width : 400
              });
          };

          /**
           * @public
           */
          this.resume = function() {
              registerEvents();
              $(BASE64_TEXT).val("");
              formStateView.reset();
              presenter.usersLoggedIn();
          };

          /**
           * @public
           */
          this.pause = function() {
              // clear the list of logged in users in the dialog
              $('.hp-dependencies', FORM).empty();
              removeEvents();
              $(BASE64_TEXT).val("");
              formStateView.reset();
          };

        }

        return new CertificateImportView();
    }());

    return CertificateImportView;
});
