/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */
define(["dojo/parser",
        "dojo/query",
        "dojo/_base/lang",
        "dojo/_base/declare",
        "dijit/registry",
        "dojox/html/entities",
        "qpid/common/updater",
        "qpid/common/util",
        "qpid/common/formatter",
        "qpid/management/addQueue",
        "qpid/management/addExchange",
        "qpid/management/addLogger",
        "qpid/management/query/QueryGrid",
        "qpid/management/editVirtualHost",
        "qpid/common/StatisticsWidget",
        "dojo/text!showVirtualHost.html",
        "dijit/Dialog",
        "dgrid/Grid",
        "dgrid/Selector",
        "dgrid/Keyboard",
        "dgrid/Selection",
        "dgrid/extensions/Pagination",
        "dgrid/extensions/ColumnResizer",
        "dgrid/extensions/DijitRegistry",
        "dstore/Memory",
        "dstore/Trackable",
        "dojo/aspect",
        "dojo/domReady!"],
    function (parser,
              query,
              lang,
              declare,
              registry,
              entities,
              updater,
              util,
              formatter,
              addQueue,
              addExchange,
              addLogger,
              QueryGrid,
              editVirtualHost,
              StatisticsWidget,
              template,
              Dialog,
              Grid,
              Selector,
              Keyboard,
              Selection,
              Pagination,
              ColumnResizer,
              DijitRegistry,
              MemoryStore,
              TrackableStore,
              aspect)
    {

        function VirtualHost(kwArgs)
        {
            this.controller = kwArgs.controller;
            this.modelObj = kwArgs.tabData.modelObject;
            this.management = this.controller.management;
            this.name = this.modelObj.name;
        }

        VirtualHost.prototype.getTitle = function ()
        {
            return "VirtualHost: " + this.name;
        };

        VirtualHost.prototype.open = function (contentPane)
        {
            var that = this;
            this.contentPane = contentPane;

            var containerNode = contentPane.containerNode;
            containerNode.innerHTML = template;
            parser.parse(containerNode)
                .then(function (instances)
                {
                    that.vhostUpdater = new Updater(that);

                    var addQueueButton = query(".addQueueButton", containerNode)[0];
                    registry.byNode(addQueueButton).on("click", function (evt)
                    {
                        addQueue.show(that.management, that.modelObj)
                    });

                    var deleteQueueButton = query(".deleteQueueButton", containerNode)[0];
                    registry.byNode(deleteQueueButton).on("click", function (evt)
                    {
                        that._deleteSelectedItems(that.vhostUpdater.queuesGrid,
                            {type: "queue", parent: that.modelObj},
                            "delete", "queue");
                    });

                    const clearQueueButton = query(".clearQueueButton", containerNode)[0];
                    registry.byNode(clearQueueButton).on("click", function (evt)
                    {
                        that._clearQueues(that.vhostUpdater.queuesGrid);
                    });

                    var addExchangeButton = query(".addExchangeButton", containerNode)[0];
                    registry.byNode(addExchangeButton).on("click", function (evt)
                    {
                        addExchange.show(that.management, that.modelObj);
                    });

                    var deleteExchangeButton = query(".deleteExchangeButton", containerNode)[0];
                    registry.byNode(deleteExchangeButton).on("click", function (evt)
                    {
                        that._deleteSelectedItems(that.vhostUpdater.exchangesGrid,
                            {type: "exchange", parent: that.modelObj},
                            "delete", "exchange");
                    });

                    var closeConnectionButton = query(".closeConnectionButton", containerNode)[0];
                    registry.byNode(closeConnectionButton).on("click", function (evt)
                    {
                        that._deleteSelectedItems(that.vhostUpdater.connectionsGrid,
                            {type: "connection"},
                            "close", "connection");
                    });

                    var addLoggerButtonNode = query(".addVirtualHostLogger", contentPane.containerNode)[0];
                    var addLoggerButton = registry.byNode(addLoggerButtonNode);
                    addLoggerButton.on("click", function (evt)
                    {
                        addLogger.show(that.management, that.modelObj, "VirtualHostLogger");
                    });

                    var deleteLoggerButtonNode = query(".deleteVirtualHostLogger", contentPane.containerNode)[0];
                    var deleteLoggerButton = registry.byNode(deleteLoggerButtonNode);
                    deleteLoggerButton.on("click", function (evt)
                    {
                        that._deleteSelectedItems(that.vhostUpdater.virtualHostLoggersGrid,
                            {type: "virtualhostlogger", parent: that.modelObj},
                            "delete", "virtual host logger");
                    });

                    that.stopButton = registry.byNode(query(".stopButton", containerNode)[0]);
                    that.startButton = registry.byNode(query(".startButton", containerNode)[0]);
                    that.editButton = registry.byNode(query(".editButton", containerNode)[0]);
                    that.downloadButton = registry.byNode(query(".downloadButton", containerNode)[0]);
                    that.downloadButton.on("click", function (e)
                    {
                        var suggestedAttachmentName = encodeURIComponent(that.name + ".json");
                        that.management.download(that.modelObj, {
                            contentDispositionAttachmentFilename: suggestedAttachmentName
                        }, "extractConfig");
                    });

                    that.deleteButton = registry.byNode(query(".deleteButton", containerNode)[0]);
                    that.deleteButton.on("click", function (e)
                    {
                        if (confirm("Deletion of virtual host will delete message data.\n\n"
                            + "Are you sure you want to delete virtual host  '"
                            + entities.encode(String(that.name)) + "'?"))
                        {
                            that.management.remove(that.modelObj)
                                .then(function (result)
                                {
                                    that.destroy();
                                });
                        }
                    });
                    that.startButton.on("click", function (event)
                    {
                        that.startButton.set("disabled", true);
                        that.management.update(that.modelObj, {desiredState: "ACTIVE"})
                            .then();
                    });

                    that.stopButton.on("click", function (event)
                    {
                        if (confirm("Stopping the virtual host will also stop its children. "
                            + "Are you sure you want to stop virtual host '"
                            + entities.encode(String(that.name)) + "'?"))
                        {
                            that.stopButton.set("disabled", true);
                            that.management.update(that.modelObj, {desiredState: "STOPPED"})
                                .then();
                        }
                    });

                    that.editButton.on("click", function (event)
                    {
                        editVirtualHost.show(that.management, that.modelObj);
                    });

                    var addVirtualHostAccessControlProviderButton = registry.byNode(query(
                        ".addVirtualHostAccessControlProvider",
                        contentPane.containerNode)[0]);
                    addVirtualHostAccessControlProviderButton.on("click", function () {
                        require(["qpid/management/addAccessControlProvider"],
                            function (addAccessControlProvider) {
                                addAccessControlProvider.show(that.management, that.modelObj);
                            });
                    });

                    var deleteVirtualHostAccessControlProviderButton = registry.byNode(query(
                        ".deleteVirtualHostAccessControlProvider",
                        contentPane.containerNode)[0]);
                    deleteVirtualHostAccessControlProviderButton.on("click", function () {
                        that._deleteSelectedItems(that.vhostUpdater.virtualHostAccessControlProviderGrid,
                            {
                                type: "virtualhostaccesscontrolprovider",
                                parent: that.modelObj
                            },
                            "delete", "virtual host access control provider");
                    });

                    const addConnectionLimitProviderButton = registry.byNode(
                        query(".addVirtualHostConnectionLimitProvider", contentPane.containerNode)[0]);
                    addConnectionLimitProviderButton.on("click", function () {
                        require(["qpid/management/addConnectionLimitProvider"],
                            function (addConnectionLimitProvider)
                            {
                                addConnectionLimitProvider.show(that.management, that.modelObj);
                            });
                    });

                    const deleteConnectionLimitProviderButton = registry.byNode(
                        query(".deleteVirtualHostConnectionLimitProvider", contentPane.containerNode)[0]);
                    deleteConnectionLimitProviderButton.on("click", function () {
                        that._deleteSelectedItems(that.vhostUpdater.virtualHostConnectionLimitProviderGrid,
                            {
                                type: "virtualhostconnectionlimitprovider",
                                parent: that.modelObj
                            },
                            "delete", "virtual host connection limit provider");
                    });

                    that.vhostUpdater.update(function ()
                    {
                        updater.add(that.vhostUpdater);
                    });
                });
        };

        VirtualHost.prototype._deleteSelectedItems = function (dgrid, modelObj, friendlyAction, friendlyCategoryName)
        {
            let confirmed = false;
            var selected = [];
            var selection = dgrid.selection;
            for (var item in selection)
            {
                if (selection.hasOwnProperty(item) && selection[item])
                {
                    selected.push(item);
                }
            }
            if (selected.length > 0)
            {
                var plural = selected.length === 1 ? "" : "s";
                if (confirm(lang.replace("Are you sure you want to {0} {1} {2}{3}?",
                    [friendlyAction,
                        selected.length,
                        entities.encode(friendlyCategoryName),
                        plural])))
                {
                    this.management
                        .remove(modelObj, {"id": selected})
                        .then(lang.hitch(this, function (responseData)
                        {
                            dgrid.clearSelection();
                            this.vhostUpdater.update();
                        }));
                    confirmed = true;
                }
            }
            return confirmed;
        };

        VirtualHost.prototype._clearQueues = function (dgrid)
        {
            let selected = [];
            for (let item in dgrid.selection)
            {
                if (dgrid.selection.hasOwnProperty(item) && dgrid.selection[item])
                {
                    selected.push(item);
                }
            }
            if (selected.length > 0)
            {
                const plural = selected.length === 1 ? "" : "s";
                if (confirm(lang.replace("Are you sure you want to purge {0} queue{1}?", [selected.length, plural])))
                {
                    const modelObj = {
                        type: "virtualhost",
                        name: "clearQueues",
                        parent: this.modelObj
                    };
                    this.management.update(modelObj, {"queues" : selected}).then(lang.hitch(this, function ()
                    {
                        dgrid.clearSelection();
                        this.vhostUpdater.update();
                    }));
                }
            }
        };

        VirtualHost.prototype.close = function ()
        {
            updater.remove(this.vhostUpdater);
        };

        VirtualHost.prototype.destroy = function ()
        {
            this.close();
            this.contentPane.onClose();
            this.controller.tabContainer.removeChild(this.contentPane);
            this.contentPane.destroyRecursive();
        };

        function Updater(virtualHost)
        {
            var vhost = virtualHost.modelObj;
            var controller = virtualHost.controller;
            var node = virtualHost.contentPane.containerNode;

            this.tabObject = virtualHost;
            this.contentPane = virtualHost.contentPane;
            this.management = controller.management;
            this.modelObj = vhost;
            this.vhostData = {};
            var that = this;

            function findNode(name)
            {
                return query("." + name, node)[0];
            }

            function storeNodes(names)
            {
                for (var i = 0; i < names.length; i++)
                {
                    that[names[i]] = findNode(names[i]);
                }
            }

            this.virtualhostStatisticsNode = findNode("virtualhostStatistics");

            storeNodes(["name",
                "type",
                "state",
                "durable",
                "lifetimePolicy",
                "virtualHostDetailsContainer",
                "connectionThreadPoolSize",
                "statisticsReportingPeriod",
                "housekeepingCheckPeriod",
                "housekeepingThreadCount",
                "storeTransactionIdleTimeoutClose",
                "storeTransactionIdleTimeoutWarn",
                "storeTransactionOpenTimeoutClose",
                "storeTransactionOpenTimeoutWarn",
                "virtualHostConnections",
                "virtualHostChildren"]);


            var CustomGrid = declare([QueryGrid, Selector]);

            this.queuesGrid = new CustomGrid({
                detectChanges: true,
                rowsPerPage: 10,
                transformer: util.queryResultToObjects,
                management: this.management,
                parentObject: this.modelObj,
                category: "Queue",
                selectClause: "id, name, type, consumerCount, queueDepthMessages, queueDepthBytes",
                orderBy: "name",
                selectionMode: 'none',
                deselectOnRefresh: false,
                allowSelectAll: true,
                columns: [
                    {
                        field: "selected",
                        label: 'All',
                        selector: 'checkbox'
                    }, {
                        label: "Name",
                        field: "name"
                    }, {
                        label: "Type",
                        field: "type"
                    }, {
                        label: "Consumers",
                        field: "consumerCount"
                    }, {
                        label: "Depth (msgs)",
                        field: "queueDepthMessages"
                    }, {
                        label: "Depth (bytes)",
                        field: "queueDepthBytes",
                        formatter: function (value, object)
                        {
                            var bytesFormat = formatter.formatBytes(value);
                            return bytesFormat.toString();
                        }
                    }
                ]
            }, findNode("queues"));
            this.queuesGrid.on('rowBrowsed', function (event) {
                controller.showById(event.id);
            });
            this.queuesGrid.startup();

            this.exchangesGrid = new CustomGrid({
                detectChanges: true,
                rowsPerPage: 10,
                transformer: util.queryResultToObjects,
                management: this.management,
                parentObject: this.modelObj,
                category: "Exchange",
                selectClause: "id, name, type, bindingCount",
                orderBy: "name",
                selectionMode: 'none',
                deselectOnRefresh: false,
                allowSelectAll: true,
                allowSelect: function (row)
                {
                    var item = row.data;
                    var isStandard = item && item.name && util.isReservedExchangeName(item.name);
                    return !isStandard;
                },
                columns: [
                    {
                        field: "selected",
                        label: 'All',
                        selector: 'checkbox'
                    }, {
                        label: "Name",
                        field: "name"
                    }, {
                        label: "Type",
                        field: "type"
                    }, {
                        label: "Binding Count",
                        field: "bindingCount"
                    }
                ]
            }, findNode("exchanges"));
            this.exchangesGrid.on('rowBrowsed', function (event) {
                controller.showById(event.id);
            });
            this.exchangesGrid.startup();

            this.connectionsGrid = new CustomGrid({
                detectChanges: true,
                rowsPerPage: 10,
                transformer: lang.hitch(this, this._transformConnectionData),
                management: this.management,
                parentObject: this.modelObj,
                category: "Connection",
                selectClause: "id, name, principal, port.name AS port, transport, sessionCount, messagesIn, bytesIn, messagesOut, bytesOut",
                orderBy: "name",
                selectionMode: 'none',
                deselectOnRefresh: false,
                allowSelectAll: true,
                columns: [
                    {
                        field: "selected",
                        label: 'All',
                        selector: 'checkbox'
                    }, {
                        label: "Name",
                        field: "name"
                    }, {
                        label: "User",
                        field: "principal"
                    }, {
                        label: "Port",
                        field: "port"
                    }, {
                        label: "Transport",
                        field: "transport"
                    }, {
                        label: "Sessions",
                        field: "sessionCount"
                    }, {
                        label: "Msgs In",
                        field: "msgInRate"
                    }, {
                        label: "Bytes In",
                        field: "bytesInRate"
                    }, {
                        label: "Msgs Out",
                        field: "msgOutRate"
                    }, {
                        label: "Bytes Out",
                        field: "bytesOutRate"
                    }
                ]
            }, findNode("connections"));
            this.connectionsGrid.on('rowBrowsed', function (event) {
                controller.showById(event.id);
            });
            this.connectionsGrid.startup();

            this.virtualHostLoggersGrid = new CustomGrid({
                detectChanges: true,
                rowsPerPage: 10,
                transformer: util.queryResultToObjects,
                management: this.management,
                parentObject: this.modelObj,
                category: "VirtualHostLogger",
                selectClause: "id, name, type, errorCount, warnCount",
                orderBy: "name",
                selectionMode: 'none',
                deselectOnRefresh: false,
                allowSelectAll: true,
                columns: [
                    {
                        field: "selected",
                        label: 'All',
                        selector: 'checkbox'
                    }, {
                        label: "Name",
                        field: "name"
                    }, {
                        label: "Type",
                        field: "type"
                    }, {
                        label: "Errors",
                        field: "errorCount"
                    }, {
                        label: "Warnings",
                        field: "warnCount"
                    }
                ]
            }, findNode("loggers"));
            this.virtualHostLoggersGrid.on('rowBrowsed', function (event) {
                controller.showById(event.id);
            });
            this.virtualHostLoggersGrid.startup();

            var Store = MemoryStore.createSubclass(TrackableStore);
            this._policyStore = new Store({
                data: [],
                idProperty: "pattern"
            });

            var PolicyGrid = declare([Grid, Keyboard, Selection, Pagination, ColumnResizer, DijitRegistry]);
            this._policyGrid = new PolicyGrid({
                rowsPerPage: 10,
                selectionMode: 'none',
                deselectOnRefresh: false,
                allowSelectAll: true,
                cellNavigation: true,
                className: 'dgrid-autoheight',
                pageSizeOptions: [10, 20, 30, 40, 50, 100],
                adjustLastColumn: true,
                collection: this._policyStore,
                highlightRow: function () {
                },
                columns: [
                    {
                        label: 'Node Type',
                        field: "nodeType"
                    }, {
                        label: "Pattern",
                        field: "pattern"
                    }, {
                        label: "Create On Publish",
                        field: "createdOnPublish",
                        selector: 'checkbox'
                    }, {
                        label: "Create On Consume",
                        field: "createdOnConsume",
                        selector: 'checkbox'
                    }, {
                        label: "Attributes",
                        field: "attributes",
                        sortable: false,
                        formatter: function (value, object)
                        {
                            var markup = "";
                            if (value)
                            {
                                markup = "<div class='keyValuePair'>";
                                for (var key in value)
                                {
                                    markup += "<div>" + entities.encode(String(key)) + "="
                                        + entities.encode(String(value[key])) + "</div>";
                                }
                                markup += "</div>"
                            }
                            return markup;
                        }
                    }
                ]
            }, findNode("policies"));

            this._policyGrid.startup();
            this._nodeAutoCreationPolicies = registry.byNode(findNode("nodeAutoCreationPolicies"));

            aspect.after(this._nodeAutoCreationPolicies, "toggle", lang.hitch(this, function () {
                if (this._nodeAutoCreationPolicies.get("open") === true)
                {
                    this._policyGrid.refresh();
                }
            }));

            this.virtualHostAccessControlProviderGrid = new CustomGrid({
                detectChanges: true,
                rowsPerPage: 10,
                transformer: util.queryResultToObjects,
                management: this.management,
                parentObject: this.modelObj,
                category: "VirtualHostAccessControlProvider",
                selectClause: "id, name, state, type, priority",
                orderBy: "name",
                selectionMode: 'none',
                deselectOnRefresh: false,
                allowSelectAll: true,
                columns: [
                    {
                        field: "selected",
                        label: 'All',
                        selector: 'checkbox'
                    }, {
                        label: "Name",
                        field: "name"
                    }, {
                        label: "State",
                        field: "state"
                    }, {
                        label: "Type",
                        field: "type"
                    }, {
                        label: "Priority",
                        field: "priority"
                    }
                ]
            }, findNode("virtualHostAccessControlProviders"));
            this.virtualHostAccessControlProviderGrid.on('rowBrowsed', function (event) {
                controller.showById(event.id);
            });
            this.virtualHostAccessControlProviderGrid.startup();

            this.virtualHostConnectionLimitProviderGrid = new CustomGrid({
                detectChanges: true,
                rowsPerPage: 10,
                transformer: util.queryResultToObjects,
                management: this.management,
                parentObject: this.modelObj,
                category: "VirtualHostConnectionLimitProvider",
                selectClause: "id, name, state, type",
                orderBy: "name",
                selectionMode: 'none',
                deselectOnRefresh: false,
                allowSelectAll: true,
                columns: [
                    {
                        field: "selected",
                        label: 'All',
                        selector: 'checkbox'
                    }, {
                        label: "Name",
                        field: "name"
                    }, {
                        label: "State",
                        field: "state"
                    }, {
                        label: "Type",
                        field: "type"
                    }
                ]
            }, findNode("virtualHostConnectionLimitProviders"));
            this.virtualHostConnectionLimitProviderGrid.on('rowBrowsed', function (event) {
                controller.showById(event.id);
            });
            this.virtualHostConnectionLimitProviderGrid.startup();
        }

        Updater.prototype.update = function (callback)
        {
            if (!this.contentPane.selected && !callback)
            {
                return;
            }
            this.management.load(this.modelObj,
                {
                    excludeInheritedContext: true,
                    depth: 0
                })
                .then(lang.hitch(this, function (data)
                {
                    this._updateFromData(data, callback);
                }), lang.hitch(this, function (error)
                {
                    util.tabErrorHandler(error,
                        {
                            updater: this,
                            contentPane: this.tabObject.contentPane,
                            tabContainer: this.tabObject.controller.tabContainer,
                            name: this.modelObj.name,
                            category: "Virtual Host"
                        });
                }));
        };

        Updater.prototype._updateFromData = function (data, callback)
        {
            this.vhostData = data || {name: this.modelObj.name};

            if (!this.virtualhostStatistics)
            {
                this.virtualhostStatistics = new StatisticsWidget({
                    category: "VirtualHost",
                    modelObj: this.modelObj,
                    type: this.vhostData.type,
                    management: this.management,
                    defaultStatistics: ["messagesIn", "messagesOut", "totalDepthOfQueuesMessages"]
                });
                this.virtualhostStatistics.placeAt(this.virtualhostStatisticsNode);
                this.virtualhostStatistics.startup();
            }

            if (callback)
            {
                callback();
            }

            try
            {
                this._update();
            }
            catch (e)
            {
                if (console && console.error)
                {
                    console.error(e);
                }
            }
        };

        Updater.prototype._update = function ()
        {
            this.tabObject.startButton.set("disabled", !this.vhostData.state || this.vhostData.state !== "STOPPED");
            this.tabObject.stopButton.set("disabled", !this.vhostData.state || this.vhostData.state !== "ACTIVE");
            this.tabObject.editButton.set("disabled", !this.vhostData.state || this.vhostData.state === "UNAVAILABLE");
            this.tabObject.downloadButton.set("disabled", !this.vhostData.state || this.vhostData.state !== "ACTIVE");
            this.tabObject.deleteButton.set("disabled", !this.vhostData.state);

            this.virtualhostStatistics.update(this.vhostData.statistics);

            this._updateHeader();

            this.virtualHostChildren.style.display = this.vhostData.state === "ACTIVE" ? "block" : "none";

            if (this.vhostData.state === "ACTIVE")
            {
                this.connectionsGrid.updateData();
                this.queuesGrid.updateData();
                this.exchangesGrid.updateData();
                this.virtualHostLoggersGrid.updateData();
                this.virtualHostAccessControlProviderGrid.updateData();
                this.virtualHostConnectionLimitProviderGrid.updateData();
            }

            if (this.details)
            {
                this.details.update(this.vhostData);
            }
            else
            {
                var thisObj = this;
                require(["qpid/management/virtualhost/" + this.vhostData.type.toLowerCase() + "/show"],
                    function (VirtualHostDetails)
                    {
                        thisObj.details = new VirtualHostDetails({
                            containerNode: thisObj.virtualHostDetailsContainer,
                            parent: thisObj
                        });
                        thisObj.details.update(thisObj.vhostData);
                    });
            }
            util.updateSyncDStore(this._policyStore, this.vhostData.nodeAutoCreationPolicies || [], "pattern");
        };

        Updater.prototype._updateHeader = function ()
        {
            this.name.innerHTML = entities.encode(String(this.vhostData["name"]));
            this.type.innerHTML = entities.encode(String(this.vhostData["type"]));
            this.state.innerHTML = entities.encode(String(this.vhostData["state"]));
            this.durable.innerHTML = entities.encode(String(this.vhostData["durable"]));
            this.lifetimePolicy.innerHTML = entities.encode(String(this.vhostData["lifetimePolicy"]));
            util.updateUI(this.vhostData,
                ["housekeepingCheckPeriod",
                    "housekeepingThreadCount",
                    "storeTransactionIdleTimeoutClose",
                    "storeTransactionIdleTimeoutWarn",
                    "storeTransactionOpenTimeoutClose",
                    "storeTransactionOpenTimeoutWarn",
                    "statisticsReportingPeriod",
                    "connectionThreadPoolSize"],
                this)
        };

        Updater.prototype._transformConnectionData = function (data)
        {

            var sampleTime = new Date();
            var connections = util.queryResultToObjects(data);
            if (this._previousConnectionSampleTime)
            {
                var samplePeriod = sampleTime.getTime() - this._previousConnectionSampleTime.getTime();
                for (var i = 0; i < connections.length; i++)
                {
                    var connection = connections[i];
                    var oldConnection = null;
                    for (var j = 0; j < this._previousConsumers.length; j++)
                    {
                        if (this._previousConsumers[j].id === connection.id)
                        {
                            oldConnection = this._previousConsumers[j];
                            break;
                        }
                    }
                    var msgOutRate = 0;
                    var bytesOutRate = 0;
                    var bytesInRate = 0;
                    var msgInRate = 0;

                    if (oldConnection)
                    {
                        msgOutRate = (1000 * (connection.messagesOut - oldConnection.messagesOut))
                            / samplePeriod;
                        bytesOutRate = (1000 * (connection.bytesOut - oldConnection.bytesOut)) / samplePeriod;
                        msgInRate = (1000 * (connection.messagesIn - oldConnection.messagesIn)) / samplePeriod;
                        bytesInRate = (1000 * (connection.bytesIn - oldConnection.bytesIn)) / samplePeriod;
                    }

                    connection.msgOutRate = msgOutRate.toFixed(0) + "msg/s";
                    var bytesOutRateFormat = formatter.formatBytes(bytesOutRate);
                    connection.bytesOutRate = bytesOutRateFormat.value + bytesOutRateFormat.units + "/s";
                    connection.msgInRate = msgInRate.toFixed(0) + "msg/s";
                    var bytesInRateFormat = formatter.formatBytes(bytesInRate);
                    connection.bytesInRate = bytesInRateFormat.value + bytesInRateFormat.units + "/s";
                }
            }
            this._previousConnectionSampleTime = sampleTime;
            this._previousConsumers = connections;
            return connections;
        };

        return VirtualHost;
    });
