// (C) Copyright 2020 Hewlett-Packard Enterprise Company, L.P.
define([ 'hp/services/REST','hp/model/DevelopmentSettings','jquery'],
function(REST, settings) {"use strict";

    var NetworkSetupService = (function() {

        var TASK_STATUS_TIMEOUT = 3000, // msec
            REACHABLE_TIMEOUT = 10000, // msec
            iPv6Disabled = false,    // unless explicitly disabled ipv6 should be displayed
            trapForwardingDisabled = true, // unless explicitly disabled trap forwarding should be displayed
            apiVersion  = 100;
        /**
         * @constructor Singleton class containing service logic for the initial
         *              network settings page
         * @type {NetworkSetupService}
         */
        function NetworkSetupService() {

            /**
             * Translate the network object used by the UI to FTS's network DTO.
             *
             * @param {networkObject}
             */
            function getFtsNetworkDTO(networkObject) {

                var networkDTO = {
                    ipv4Type : networkObject.ipv4Type,
                    ipv6Type : networkObject.ipv6Type,
                    hostname : networkObject.hostname,
                    dynamicDns : networkObject.dnsFromDHCP,
                    ipv4Subnet: networkObject.ipv4Subnet,
                    ipv4Gateway: networkObject.ipv4Gateway,
                    ipv6Subnet: networkObject.ipv6Subnet,
                    ipv6Gateway: networkObject.ipv6Gateway,
                    confOneNode: networkObject.confOneNode,
                    activeNode: networkObject.localNodeID,
                    app1Ipv4Addr: networkObject.app1Ipv4Addr,
                    macAddress: networkObject.macAddress,
                    device: networkObject.device,
                    interfaceName: networkObject.interfaceName
                };

                if (!networkObject.dnsFromDHCP) {
                    networkDTO.domainName=networkObject.domainName;
                    networkDTO.ipv4NameServers = [];
                    if (networkObject.priDns) {
                        networkDTO.ipv4NameServers.push(networkObject.priDns);
                    }
                    if (networkObject.altDns) {
                        networkDTO.ipv4NameServers.push(networkObject.altDns);
                    }
                }

                return networkDTO;
            }

            /**
             * Translate the data for a single node from FTS network DTO to UI network object.
             *
             * @param {object} networkObject UI network object to update
             * @param {string} objTag Node to update in the network object
             * @param {NetworkDTO} networkDTO FTS network DTO to read
             * @param {string} dtoTag Node to read from the DTO
             */
            function getUINetworkObjectNode(networkObject, objTag, networkDTO, dtoTag) {
                if (!networkObject.addrs) {
                    networkObject.addrs = {};
                }
                networkObject.addrs[objTag] = {
                    ipv4: networkDTO[dtoTag + "Ipv4Addr"],
                    ipv6: networkDTO[dtoTag + "Ipv6Addr"]
                };
                if ("app1Ipv4Alias" in networkDTO) { // all aliases will be present as properties
                    networkObject.addrs[objTag].ipv4_2 =  networkDTO[dtoTag + "Ipv4Alias"];
                    networkObject.addrs[objTag].ipv6_2 =  networkDTO[dtoTag + "Ipv6Alias"];
                }

            }

            /**
             * Translate FTS's network DTO to the network object used by the UI.
             *
             * @param {networkDTO}
             */
            function getUINetworkObject(networkDTO) {
                var networkObject = {
                    ipv4Type : networkDTO.ipv4Type,
                    ipv6Type : networkDTO.ipv6Type,
                    hostname : networkDTO.hostname,
                    domainName: networkDTO.domainName,
                    ipv4Subnet: networkDTO.ipv4Subnet,
                    ipv4Gateway: networkDTO.ipv4Gateway,
                    ipv6Subnet: networkDTO.ipv6Subnet,
                    ipv6Gateway: networkDTO.ipv6Gateway,
                    confOneNode: networkDTO.confOneNode !== false,
                    localNodeID: networkDTO.activeNode,
                    dnsFromDHCP : networkDTO.dynamicDns
                };
                getUINetworkObjectNode(networkObject, 'node1', networkDTO, 'app1');
                getUINetworkObjectNode(networkObject, 'node2', networkDTO, 'app2');
                getUINetworkObjectNode(networkObject, 'cluster', networkDTO, 'virt');
                if (networkDTO.app2Ipv6Addr && networkDTO.app2Ipv6Addr != '') {
                    networkObject.twoNodeData = true;
                } else {
                    networkObject.twoNodeData = false;
                }

                networkObject.priDns = (networkDTO.ipv4NameServers.length > 0) ? networkDTO.ipv4NameServers[0] : null;
                networkObject.altDns = (networkDTO.ipv4NameServers.length > 1) ? networkDTO.ipv4NameServers[1] : null;

                // figure out the domain  in case this is the FTS and we want to automatically append the domain name
                // to the hostname that is  not fully qualified.
                if (!networkDTO.domainName) {
                    if (networkDTO.searchDomains && networkDTO.searchDomains.length !=0) {
                        networkObject.searchDomainName = networkDTO.searchDomains[0];
                    }
                }

                return networkObject;
            }

            /**
             * @public postNetwork - Send REST request to set the
             *         initial network , time and lnaguage configuration
             *
             *
             */
            this.postNetwork= function(networkObjectList,timeDto ,localeDto,serverCertificateDTO, handlers) {
                var applianceDTO = {
                        type : "ApplianceServerConfiguration",
                        applianceNetworks : networkObjectList,
                        time : timeDto,
                        locale : localeDto,
                        serverCertificate : serverCertificateDTO
                };

                REST.postObject('/rest/appliance/network-interfaces/', applianceDTO, handlers,{apiVersion: apiVersion});
            };




            /**
             * Get the current network configuration of the server.
             *
             * @param {{success:function(NetworkDTO):void, error:function(ErrorMessage):void}} handlers
             *     Handler functions for success and error conditions.
             */
            this.getNetworkConfiguration = function(handlers) {
                REST.getURI('/rest/appliance/configuration/networkconfig', {
                    success: function(networkDTO) {
                        handlers.success(getUINetworkObject(networkDTO));
                    },
                    error: handlers.error
                });
            };



            this.getSelectedNetworkConfiguration = function(macAddress, handlers) {
                var uri = '/rest/appliance/network-interfaces/'+macAddress;
                REST.getURI(uri, {
                    success: function(multiNicDTO) {
                        handlers.success(multiNicDTO);
                    },
                    error: handlers.error
                },{apiVersion: apiVersion});
            };

            /**
             * Retrieve the nics that are configured.
             *
             * @param {{success:function(NetworkDTO):void, error:function(ErrorMessage):void}} handlers
             *     Handler functions for success and error conditions.
             */
            this.getConfiguredNICs = function(handlers) {
                REST.getURI('/rest/appliance/network-interfaces', {
                    success: function(multiNicDTO) {
                        handlers.success(multiNicDTO);
                    },
                    error: handlers.error
                },{apiVersion: apiVersion});
            };

            /**.
             * Retrieve the nics that are not configured.
             *
             * @param {{success:function(NetworkDTO):void, error:function(ErrorMessage):void}} handlers
             *     Handler functions for success and error conditions.
             */
            this.getUnconfiguredNICs = function(handlers) {
                REST.getURI('/rest/appliance/network-interfaces/mac-addresses', {
                    success: function(multiNicDTO) {
                        handlers.success(multiNicDTO.members);
                    },
                    error: handlers.error
                },{apiVersion: apiVersion});
            };

            /**
             * Retrive the NIC Object of the server by Passing the Mac Address.
             *
             * @param {{success:function(MultiNicDTO):void, error:function(ErrorMessage):void}} handlers
             *     Handler functions for success and error conditions.
             */
            this.getConfiguredNIC = function(mac,handlers) {
                REST.getURI('/rest/appliance/network-interfaces/'+mac, {
                    success: function(multiNicDTO) {
                        handlers.success(getUINetworkObject(multiNicDTO));
                    },
                    error: handlers.error
                },{apiVersion: apiVersion});
            };

            /**
             * Get the status of a task tracker task.
             *
             * @param {string} hostname The appliance hostname to talk to (== null for current)
             * @param {string} uri The uri to use to get the task status
             * @param {{success:function(TaskResourceDTO):void, error:function(ErrorMessage):void}
             *     handlers Handler functions for success and error conditions.
             */
            this.getTaskStatus = function(hostname, uri, handlers) {
                // Get the standard Ajax options for a REST GET call.

                if (hostname) {
                    uri = "https://" + hostname + uri;
                }
                var options = REST.getAjaxOptions(uri, 'GET', handlers);
                // Set a short timeout on the call.
                options.timeout = TASK_STATUS_TIMEOUT;

                // Issue the call.
                $.ajax(options);
            };

            /**
             * Find out whether a host is reachable, by trying to read its controller-state.json file.
             *
             * @param {string} hostname Hostname to attempt, or null for current
             * @param {object} handlers Success and error handlers
             */
            this.checkReachable = function(hostname,ssl, handlers) {

                 jQuery.support.cors = true;
                 var destUrl;


                 var defaultHost = window.location.href.split("/")[2];

                 if ( ssl || $.browser.msie) {
                     destUrl = 'https://' + (hostname ? hostname : defaultHost) + '/controller-state.json';
                 } else {
                     destUrl = 'http://' + (hostname ? hostname : defaultHost) + '/controller-state.json';
                 }
                $.ajax({
                    url : destUrl,
                    type : 'GET',
                    success : handlers.success,
                    error : handlers.error,
                    dataType : "json",
                    cache: false,
                    timeout: REACHABLE_TIMEOUT
                });
            };



            /**
             * Find out whether the peer node is valid to be used as a standby node in our cluster.
             *
             * @param {object} handlers The success and error handler functions.
             */
            this.validatePeerNode = function(handlers) {
                handlers.success(true);
            };

            /**
             * @private Exposed only for unit tests.
             */
            this._getFtsNetworkDTO = function(networkObject) {
                return getFtsNetworkDTO(networkObject);
            };
             /**
             * @public hook for the partners to disable IPV6
             */
            this.setIPv6Disabled = function(disableIPv6Flag) {
                iPv6Disabled=disableIPv6Flag;
            };

             /**
             * @public Exposed only for unit tests.
             */
            this.getIPv6Disabled = function() {
                return (iPv6Disabled ||  settings.disableIPv6());
            };

            //Get the list of NTP servers listed in /etc/ntp.conf file
            this.getNTPservers = function(handlers) {
                REST.getURI('/rest/appliance/configuration/timeconfig/ntp', handlers);
            };
            //Get the local system date and time
            this.getDateTime = function(handlers) {
                REST.getURI('/rest/appliance/configuration/timeconfig/localtime', handlers);
            };
            //Get the locale of the system
            this.getLocale = function(handlers) {
                REST.getURI('/rest/appliance/configuration/timeconfig/locale', handlers);
            };
            //Get the list of locales available in the system
            this.getLocales = function(handlers)
            {
                REST.getURI('/rest/appliance/configuration/timeconfig/locales', handlers);
            };
            //Get the product config
            this.getProductConfig = function(handlers)
            {
                REST.getURI('/fts/rest/appliance/product-config', handlers);
            };
            this.setTrapForwardingDisabled = function(disableTrapForwarding)
            {
                trapForwardingDisabled = disableTrapForwarding;
            };
           this.getTrapForwardingDisabled = function(){
                return trapForwardingDisabled;
            };
        }

        return new NetworkSetupService();
    }());

    return NetworkSetupService;
});

