// (C) Copyright 2020 Hewlett-Packard Enterprise Company, L.P.
define(['hp/core/EventDispatcher',
        'hp/core/Localizer',
        'hp/model/Upload',
        'fs/services/settings/ApplianceUpdateService',
        'fs/model/settings/ApplianceUpgradeResource'],
function(EventDispatcher, localizer, Upload, service, resource) {"use strict";

    var ApplianceUpdatePresenter = ( function() {

        var upload = null;

        function ApplianceUpdatePresenter() {
            var dispatcher = new EventDispatcher();

            var estimatedTimeFlag = true;
            //Time interval to refresh the upgrade estimated time
            var estimatedTimeInterval = 60000;
            var estimatedTimeValue = 0;
            var uploadErrorHandler = null;
            var uploadSuccessHandler = null;
            var uploadCancelHandler = null;
            var uploadProgressHandler = null;



            function onUpgradeStatusSuccess(data){
                dispatcher.fire("getUpgradeStatusSuccess", data);
            }

            function onUpgradeStatusError(errInfo){
                // TODO:
            }
            function onUploadError(){
                return function (result) {
                    dispatcher.fire("uploadError", result.errorInfo);
                };
            }

            function onUploadSuccess(){
                return function (result) {
                    dispatcher.fire("uploadSuccess", result.data);
                };
            }
            function onUploadProgress(){
                return function (result) {
                    dispatcher.fire("uploadProgress", result);
                };
            }
            function onUploadCancel(){
                return function (result) {
                    dispatcher.fire("uploadCancel", result.data);
                };
            }
            function removeUpdateHandlers(){
                upload.off('success', uploadSuccessHandler);
                upload.off('progressChange', uploadProgressHandler);
                upload.off('error', uploadErrorHandler);
                upload.off('cancel', uploadCancelHandler);
            }

            function registerEvents(){
                resource.on("usersLoggedInSuccess", function(data) {
                    dispatcher.fire("usersLoggedInSuccess", data);
                  });
                resource.on("usersLoggedInError", function(errorInfo) {
                    dispatcher.fire("usersLoggedInError", errorInfo);
                  });
                resource.on("applianceHealthSuccess" ,function(data) {
                    dispatcher.fire("applianceHealthSuccess", data);
                });
                resource.on("applianceHealthError" ,function(data) {
                    dispatcher.fire("applianceHealthError", data);
                });
            }

            function removeEvents() {
                resource.off("usersLoggedInSuccess", function(data) {
                    dispatcher.fire("usersLoggedInSuccess", data);
                  });
                resource.off("usersLoggedInError", function(errorInfo) {
                    dispatcher.fire("usersLoggedInError", errorInfo);
                  });
                resource.off("applianceHealthSuccess" ,function(data) {
                    dispatcher.fire("applianceHealthSuccess", data);
                });
                resource.off("applianceHealthError" ,function(data) {
                    dispatcher.fire("applianceHealthError", data);
                });
            }

            this.getUpgradeStatus = function() {
                service.getUpgradeStatus({
                    success: onUpgradeStatusSuccess,
                    error: onUpgradeStatusError
                });
            };

            this.getConditions = function() {
                return resource.getConditions();
            };

            this.getFileName = function(){
                return resource.getFileName();
            };

            this.setFileName = function(data){
                resource.setFileName(data);
            };

            this.getEstimatedUpgradeTime = function(){
                return resource.getEstimatedUpgradeTime();
            };

            this.setEstimatedUpgradeTime = function(data){
                resource.setEstimatedUpgradeTime(data);
            };


            this.currentStatus = function() {
                service.currentStatus({
                    success : function(data) {
                        dispatcher.fire('upgradeStatusSuccess', data);
                    },
                    error : function(errorInfo) {
                        dispatcher.fire('upgradeStatusError', errorInfo);
                    }
                });
            };

            this.estTimeFlag = function() {
                estimatedTimeFlag = true;
            };

            this.estimatedTime = function() {
                // At first call, it will get the value from resource
                // This value is stored in resource at the end of preupgrade validation
                if(estimatedTimeFlag)
                {
                    estimatedTimeFlag = false;
                    var value = resource.getEstimatedUpgradeTime();
                    estimatedTimeValue = (value)*estimatedTimeInterval;
                    dispatcher.fire('estimatedTime', value);
                }
                else
                {
                    //For all subsequent calls, it will just decrease one minute and show to UI
                    estimatedTimeValue = estimatedTimeValue - estimatedTimeInterval;
                    if(estimatedTimeValue >= estimatedTimeInterval)
                    {
                      dispatcher.fire('estimatedTime', estimatedTimeValue/estimatedTimeInterval);
                    }
                }
            };

            this.apply = function(fileName){
                service.apply(fileName, {
                    success : function(data){
                        // The controller does not return data
                        // It might return a TaskResource in the future.
                        dispatcher.fire('applySuccess', data);
                    },
                    error : function(errorInfo){
                        dispatcher.fire('applyError', errorInfo);
                    }
                });
            };

            this.releaseNotes = function(fileName, docType, handlers) {
                service.releaseNotes(fileName, docType, handlers);
            };

            this.removeFile = function() {
                service.removeFile({
                    success : function() {
                        resource.clear();
                        resource.setFileSelection();
                        dispatcher.fire('deleteSuccess');
                    },
                    error : function(errorInfo) {
                        dispatcher.fire('deleteError', errorInfo);
                    }
                });
            };

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

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

            this.clear = function() {
                resource.clear();
            };

            this.setRebootRequired = function(value) {
                resource.setRebootRequired(value);
            };

            this.getRebootRequired = function() {
                return resource.getRebootRequired();
            };

            this.upload = function(selection) {
                if (!selection.options.uploadUri) {
                    selection.options.uploadUri = '/rest/appliance/firmware/image';
                }
                upload.init(selection.options);

                uploadErrorHandler = onUploadError();
                uploadSuccessHandler = onUploadSuccess();
                uploadProgressHandler = onUploadProgress();
                uploadCancelHandler = onUploadCancel();

                upload.on('error', uploadErrorHandler);
                upload.on('success', uploadSuccessHandler);
                upload.on('progressChange', uploadProgressHandler);
                upload.on('cancel', uploadCancelHandler);

                var id = upload.start();
                resource.setUploadID(id);

            };

            this.getRemainingTime = function() {
                return upload.getRemainingTime();
            };

            this.isUploading = function() {
                return upload.isUploading();
            };

            this.getResults = function() {
                return upload.getResults();
            };

            this.getError = function() {
                return upload.getError();
            };

            this.cancelUpload = function() {
                upload.cancel();
            };

            this.isPending = function() {
                service.isPending({
                    success : function(data) {
                        resource.clear();
                        dispatcher.fire('pendingSuccess', data);
                    },
                    error : function(errorInfo) {
                        dispatcher.fire('pendingError', errorInfo);
                    }
                });
            };

            this.getUploadID = function(){
                return resource.getUploadID();
            };

            this.usersLoggedIn = function() {
                resource.usersLoggedIn();
            };

            this.getOtherUsersLoggedInList = function() {
                return resource.getOtherUsersLoggedInList();
            };

            this.setUpdateState = function(state) {
                resource.setUpdateState(state);
            };

            this.getUpdateState = function() {
                return resource.getUpdateState();
            };

            this.getFileSelection = function() {
                return resource.getFileSelection();
            };

            this.setFileSelection = function(selection){
                resource.setFileSelection(selection);
            };

            this.getGlobalCommunityString = function(handlers){
                service.getGlobalCommunityString(handlers);
            };

            this.addOrUpdateGlobalCommunityString = function(csObject, handlers){
                service.addOrUpdateGlobalCommunityString(csObject, handlers);
            };

            this.applianceHealth = function(){
                resource.applianceHealth();
            };

            this.getAvailableDiskSpace = function(){
                return(resource.getAvailableDiskSpace()); // in GBs
            };

            this.setErrorOrWarning = function() {
                resource.setErrorOrWarning();
            };

            this.hasErrorOrWarning = function() {
                return(resource.hasErrorOrWarning());
            };

            this.clearUpdateHandlers = function() {
                removeUpdateHandlers();
            };

            this.pause = function() {
                removeEvents();
            };

            this.resume = function() {
                registerEvents();
            };

            this.init = function() {
                upload = new Upload();
                resource.clear();
                registerEvents();
            };
        }

        return new ApplianceUpdatePresenter();

    }());

    return ApplianceUpdatePresenter;
});
