#!/usr/bin/env ${PY_STRING}

#
# 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.
#

from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import
from __future__ import print_function

import os
import sys
import locale
import socket
import re
from datetime import datetime
from time import ctime, strftime, gmtime
import qpid_dispatch_site
from qpid_dispatch.management.client import Url, Node, Entity
from qpid_dispatch_internal.management.qdrouter import QdSchema
from qpid_dispatch_internal.tools import Display, Header, Sorter, YN, Commas, TimeLong, TimeShort, BodyFormat, PlainNum
from qpid_dispatch_internal.tools import NumKMG
from qpid_dispatch_internal.tools.command import (parse_args_qdstat, main,
                                                  opts_ssl_domain, opts_sasl,
                                                  opts_url)
from qpid_dispatch_internal.compat import UNICODE

def get(obj, attr):
    return getattr(obj, attr, None)

class BusManager(Node):

    schema = QdSchema()

    def __init__(self, opts):
        self.opts = opts
        super(BusManager, self).__init__(
            Node.connection(opts_url(opts), opts.router,
                            timeout=opts.timeout,
                            ssl_domain=opts_ssl_domain(opts),
                            sasl=opts_sasl(opts),
                            edge_router=opts.edge_router))
        self.show = getattr(self, opts.show)
        self.bodyFormat = BodyFormat.CSV if opts.csv else BodyFormat.CLASSIC

    def query(self, entity_type, attribute_names=None, limit=None):
        if attribute_names:
            unames = []
            for a in attribute_names:
                unames.append(UNICODE(a))
            attribute_names = unames
        return super(BusManager, self).query(entity_type, attribute_names, count=limit).get_entities()

    def connAuth(self, conn):
        ##
        ## Summarize the authentication for a connection:
        ##   no-auth
        ##   anonymous-user
        ##   <user>(PLAIN)
        ##   <user>(kerberos)
        ##   <user>(x.509)
        ##
        if not conn.isAuthenticated:
            return "no-auth"
        sasl = conn.sasl
        if sasl == "GSSAPI":
            sasl = "Kerberos"
        elif sasl == "EXTERNAL":
            sasl = "x.509"
        elif sasl == "ANONYMOUS":
            return "anonymous-user"
        if not conn.user:
            return sasl
        return "%s(%s)" % (conn.user, sasl)

    def connSecurity(self, conn):
        ##
        ## Summarize the security of a connection:
        ##   no-security
        ##   SSLv3 (cipher)
        ##   TLS (cipher)
        ##   Kerberos
        ##
        if not conn.isEncrypted:
            return "no-security"
        if conn.sasl == "GSSAPI":
            return "Kerberos"
        return "%s(%s)" % (conn.sslProto, conn.sslCipher)

    def noTrailingSlash(self, text):
        if text == None:
            return ""
        if text[-1:] == '/':
            return text[:-1]
        return text

    def displayRouterId(self):
        objects = self.query('org.apache.qpid.dispatch.router')
        router = objects[0]
        if router:
            print(router.id)

    def display_datetime_router_id(self):
        print(str(datetime.utcnow()) + " UTC")
        self.displayRouterId()
        print("")


    def displayEdges(self, show_date_id=True):
        disp = Display(prefix="  ", bodyFormat=self.bodyFormat)
        heads = []
        heads.append(Header("id"))
        heads.append(Header("host"))
        heads.append(Header("container"))
        heads.append(Header("role"))
        heads.append(Header("dir"))
        heads.append(Header("security"))
        heads.append(Header("authentication"))
        heads.append(Header("tenant"))
        
        rows = []
        objects = self.query('org.apache.qpid.dispatch.connection', limit=self.opts.limit)
        
        if not objects:
            if show_date_id:
                self.display_datetime_router_id()
            print("No Edge Router Connections")
            return

        if show_date_id:
            self.display_datetime_router_id()

        has_active = False
        
        first = objects[0]
        try:
            if first:
                active = first.active
                has_active = True
        except:
            pass
            
        if has_active:
            heads.append(Header("active"))
        
        for conn in objects:
            if conn.role == "edge":
               row = []
               row.append(conn.identity)
               row.append(conn.host)
               row.append(conn.container)
               row.append(conn.role)
               row.append(conn.dir)
               row.append(self.connSecurity(conn))
               row.append(self.connAuth(conn))
               row.append(self.noTrailingSlash(get(conn, 'tenant')))
               if has_active:
                   if conn.active:
                       row.append("yes")
                   else:
                       row.append("no")
               rows.append(row)
        
        if rows:
            title = "Connections"
        else:
            return
        
        dispRows = rows
        disp.formattedTable(title, heads, dispRows)            
        
    def displayConnections(self, show_date_id=True):
        disp = Display(prefix="  ", bodyFormat=self.bodyFormat)
        heads = []
        heads.append(Header("id"))
        heads.append(Header("host"))
        heads.append(Header("container"))
        heads.append(Header("role"))
        heads.append(Header("dir"))
        heads.append(Header("security"))
        heads.append(Header("authentication"))
        heads.append(Header("tenant"))

        rows = []
        objects = self.query('org.apache.qpid.dispatch.connection', limit=self.opts.limit)

        if show_date_id:
            self.display_datetime_router_id()

        has_uptime = False
        has_last_dlv = False

        if objects:
            first_conn = objects[0]
            try:
                lastDlvSeconds = first_conn.lastDlvSeconds
                has_last_dlv = True
            except:
                pass
            try:
                uptime = first_conn.uptimeSeconds
                has_uptime = True
            except:
                pass

        # This is so that, this qdstat can be used against older routers without Python keyerrors
        if has_last_dlv:
            heads.append(Header("last dlv"))
        if has_uptime:
            heads.append(Header("uptime"))

        for conn in objects:
            row = []
            row.append(conn.identity)
            row.append(conn.host)
            row.append(conn.container)
            row.append(conn.role)
            row.append(conn.dir)
            row.append(self.connSecurity(conn))
            row.append(self.connAuth(conn))
            row.append(self.noTrailingSlash(get(conn, 'tenant')))
            if has_last_dlv:
                if conn.lastDlvSeconds is None:
                    row.append('-')
                else:
                    row.append(TimeLong(conn.lastDlvSeconds))
            if has_uptime:
                row.append(TimeLong(conn.uptimeSeconds))
            rows.append(row)
        title = "Connections"
        dispRows = rows
        disp.formattedTable(title, heads, dispRows)

    def _addr_summary(self, addr):
        cls   = self._addr_class(addr)
        phase = self._addr_phase(addr)
        text  = self._addr_text(addr)
        if cls == '-':
            return "-"
        if cls == 'M':
            if phase == '0':
                return text
            else:
                return "%s:%s" % (phase, text)
        return "%s:%s" % (cls, text)


    def _addr_class(self, addr):
        if not addr:
            return ""
        if addr[0] == 'M'  : return "mobile"
        if addr[0] == 'R'  : return "router"
        if addr[0] == 'A'  : return "area"
        if addr[0] == 'L'  : return "local"
        if addr[0] == 'T'  : return "topo"
        if addr[0] in 'CE' : return "link-in"
        if addr[0] in 'DF' : return "link-out"
        if addr[0] == 'H'  : return "edge"
        return "unknown: %s" % addr[0]

    def _addr_text(self, addr):
        if not addr:
            return ""
        if addr[0] == 'M':
            return addr[2:]
        else:
            return addr[1:]

    def _addr_phase(self, addr):
        if not addr:
            return ""
        if addr[0] == 'M':
            return addr[1]
        return ''

    def _identity_clean(self, identity, router_id=None):
        if router_id:
            return router_id
        if not identity:
            return "-"
        pos = identity.find('/')
        if pos >= 0:
            return identity[pos + 1:]
        return identity

    def _list_clean(self, inlist):
        outlist = []
        if not inlist:
            return outlist
        for i in inlist:
            outlist.append(str(i))
        return outlist

    def displayGeneral(self, show_date_id=True):
        disp = Display(prefix="  ", bodyFormat=self.bodyFormat)
        heads = []
        heads.append(Header("attr"))
        heads.append(Header("value"))
        rows = []

        objects = self.query('org.apache.qpid.dispatch.router')

        router = objects[0]

        if show_date_id:
            self.display_datetime_router_id()

        rows.append(('Version',        router.version))
        rows.append(('Mode',           router.mode))
        rows.append(('Router Id',      router.id))
        try:
            rows.append(('Worker Threads', router.workerThreads))
        except:
            pass

        try:
            rows.append(('Uptime',        TimeLong(router.uptimeSeconds)))
        except:
            pass
            
        try:
            if router.memoryUsage > 0:
                rows.append(('VmSize', NumKMG(router.memoryUsage,
                                              base=1024)))
        except Exception:
            pass
        rows.append(('Area',          router.area))
        rows.append(('Link Routes',   PlainNum(router.linkRouteCount)))
        rows.append(('Auto Links',    PlainNum(router.autoLinkCount)))
        rows.append(('Links',         PlainNum(router.linkCount)))
        rows.append(('Nodes',         PlainNum(router.nodeCount)))
        rows.append(('Addresses',     PlainNum(router.addrCount)))
        rows.append(('Connections',   PlainNum(router.connectionCount)))

        # Overall delivery related counts.
        # These overall statistics were introduced in 1.1 version.
        # Wrap these in a try except so that newer versions of qdstat works with older version of router
        try:
            rows.append(('Presettled Count', PlainNum(router.presettledDeliveries)))
            rows.append(('Dropped Presettled Count', PlainNum(router.droppedPresettledDeliveries)))
            rows.append(('Accepted Count', PlainNum(router.acceptedDeliveries)))
            rows.append(('Rejected Count', PlainNum(router.rejectedDeliveries)))
            rows.append(('Released Count', PlainNum(router.releasedDeliveries)))
            rows.append(('Modified Count', PlainNum(router.modifiedDeliveries)))
            try:
                rows.append(('Deliveries Delayed > 1sec',  PlainNum(router.deliveriesDelayed1Sec)))
                rows.append(('Deliveries Delayed > 10sec', PlainNum(router.deliveriesDelayed10Sec)))
                rows.append(('Deliveries Stuck > 10sec',   PlainNum(router.deliveriesStuck)))
                rows.append(('Deliveries to Fallback',     PlainNum(router.deliveriesRedirectedToFallback)))
                try:
                    rows.append(('Links Blocked', PlainNum(router.linksBlocked)))
                except:
                    pass
            except:
                pass
            rows.append(('Ingress Count', PlainNum(router.deliveriesIngress)))
            rows.append(('Egress Count', PlainNum(router.deliveriesEgress)))
            rows.append(('Transit Count', PlainNum(router.deliveriesTransit)))
            rows.append(('Deliveries from Route Container', PlainNum(router.deliveriesIngressRouteContainer)))
            rows.append(('Deliveries to Route Container', PlainNum(router.deliveriesEgressRouteContainer)))
        except:
            pass

        title = "Router Statistics"
        dispRows = rows
        disp.formattedTable(title, heads, dispRows)

    def displayRouterLinks(self, show_date_id=True):
        disp = Display(prefix="  ", bodyFormat=self.bodyFormat)
        heads = []
        heads.append(Header("type"))
        heads.append(Header("dir"))
        heads.append(Header("conn id"))
        heads.append(Header("id"))
        heads.append(Header("peer"))
        heads.append(Header("class"))
        heads.append(Header("addr"))
        heads.append(Header("phs"))
        heads.append(Header("cap", Header.PLAIN_NUM))

        rows = []
        cols = ('linkType', 'linkDir', 'connectionId', 'identity', 'peer', 'owningAddr',
                'capacity', 'undeliveredCount', 'unsettledCount', 'deliveryCount',
                'presettledCount', 'droppedPresettledCount', 'acceptedCount', 'rejectedCount', 'releasedCount',
                'modifiedCount', 'deliveriesDelayed1Sec', 'deliveriesDelayed10Sec', 'deliveriesStuck',
                'creditAvailable', 'zeroCreditSeconds',
                'adminStatus', 'operStatus', 'linkName', 'priority', 'settleRate')

        objects = self.query('org.apache.qpid.dispatch.router.link', cols, limit=self.opts.limit)

        has_dropped_presettled_count = False
        has_priority = False
        has_delayed  = False
        has_stuck    = False
        has_credit   = False

        if show_date_id:
            self.display_datetime_router_id()

        if objects:
            first_row = objects[0]
            if first_row:
                if hasattr(first_row, 'droppedPresettledCount'):
                    has_dropped_presettled_count = True
                if hasattr(first_row, 'priority'):
                    has_priority = True
                if hasattr(first_row, 'deliveriesDelayed1Sec'):
                    has_delayed = True
                if hasattr(first_row, 'deliveriesStuck'):
                    has_stuck = True
                if hasattr(first_row, 'creditAvailable'):
                    has_credit = True

        if has_priority:
            heads.append(Header("pri", Header.PLAIN_NUM))
        heads.append(Header("undel", Header.PLAIN_NUM))
        heads.append(Header("unsett", Header.PLAIN_NUM))
        heads.append(Header("deliv", Header.PLAIN_NUM))
        heads.append(Header("presett", Header.PLAIN_NUM))

        if has_dropped_presettled_count:
            heads.append(Header("psdrop", Header.PLAIN_NUM))

        heads.append(Header("acc", Header.PLAIN_NUM))
        heads.append(Header("rej", Header.PLAIN_NUM))
        heads.append(Header("rel", Header.PLAIN_NUM))
        heads.append(Header("mod", Header.PLAIN_NUM))
        if has_delayed:
            heads.append(Header("delay", Header.PLAIN_NUM))
            heads.append(Header("rate", Header.PLAIN_NUM))
        if has_stuck:
            heads.append(Header("stuck", Header.PLAIN_NUM))
        if has_credit:
            heads.append(Header("cred", Header.PLAIN_NUM))
            heads.append(Header("blkd"))
        if self.opts.verbose:
            heads.append(Header("admin"))
            heads.append(Header("oper"))
            heads.append(Header("name"))

        for link in objects:
            row = []
            row.append(link.linkType)
            row.append(link.linkDir)
            row.append(link.connectionId)
            row.append(link.identity)
            row.append(link.peer)
            row.append(self._addr_class(link.owningAddr))
            row.append(self._addr_text(link.owningAddr))
            row.append(self._addr_phase(link.owningAddr))
            row.append(link.capacity)
            if has_priority:
                row.append(link.priority)
            row.append(link.undeliveredCount)
            row.append(link.unsettledCount)
            row.append(link.deliveryCount)
            row.append(link.presettledCount)
            if has_dropped_presettled_count:
                row.append(link.droppedPresettledCount)
            row.append(link.acceptedCount)
            row.append(link.rejectedCount)
            row.append(link.releasedCount)
            row.append(link.modifiedCount)
            if has_delayed:
                row.append(link.deliveriesDelayed1Sec + link.deliveriesDelayed10Sec)
                row.append(link.settleRate)
            if has_stuck:
                row.append(link.deliveriesStuck)
            if has_credit:
                row.append(link.creditAvailable)
                if link.zeroCreditSeconds > 0:
                    row.append(TimeShort(link.zeroCreditSeconds * 1000000000))
                else:
                    row.append('-')
            if self.opts.verbose:
                row.append(link.adminStatus)
                row.append(link.operStatus)
                row.append(link.linkName)
            rows.append(row)
        title = "Router Links"
        dispRows = rows
        disp.formattedTable(title, heads, dispRows)

    def displayRouterNodes(self, show_date_id=True):
        disp = Display(prefix="  ", bodyFormat=self.bodyFormat)
        heads = []
        heads.append(Header("router-id"))
        heads.append(Header("next-hop"))
        heads.append(Header("link"))
        if self.opts.verbose:
            heads.append(Header("ver"))
            heads.append(Header("cost"))
            heads.append(Header("neighbors"))
            heads.append(Header("valid-origins"))
        rows = []
        objects = self.query('org.apache.qpid.dispatch.router.node', limit=self.opts.limit)

        # Find the most recent topo change in this neighborhood.
        lastTopoChange = 0.0

        if show_date_id:
            self.display_datetime_router_id()

        for node in objects:
            row = []
            if node.lastTopoChange:
                if float(node.lastTopoChange) > lastTopoChange:
                    lastTopoChange = float(node.lastTopoChange)
            row.append(node.id)
            if node.nextHop != None:
                row.append(node.nextHop)
                row.append('-')
            else:
                row.append('-')
                row.append(node.routerLink)

            if self.opts.verbose:
                row.append(get(node, 'protocolVersion'))
                row.append(get(node, 'cost'))
                row.append('%r' % self._list_clean(node.linkState))
                row.append('%r' % self._list_clean(node.validOrigins))
            rows.append(row)
        if len(rows) > 0:
            title = "Routers in the Network"
            # Use gmtime to make times comparable across large networks.
            if lastTopoChange > 1.0:
                topoLine = "\nLast Topology Change: " + strftime('%A %b %d %H:%M:%S %Y',gmtime(lastTopoChange)) + " GMT"
                title += topoLine
            sort = Sorter(heads, rows, 'router-id')
            dispRows = sort.getSorted()
            disp.formattedTable(title, heads, dispRows)
        else:
            print("Router is Standalone - No Router List")

    def displayAddresses(self, show_date_id=True):
        disp = Display(prefix="  ", bodyFormat=self.bodyFormat)
        heads = []
        heads.append(Header("class"))
        heads.append(Header("addr"))
        heads.append(Header("phs"))
        heads.append(Header("distrib"))

        rows = []
        cols = ('distribution', 'inProcess', 'subscriberCount', 'remoteCount',
                'containerCount', 'deliveriesIngress', 'deliveriesEgress', 'deliveriesRedirectedToFallback',
                'deliveriesTransit', 'deliveriesToContainer', 'deliveriesFromContainer', 'name', 'priority')

        objects = self.query('org.apache.qpid.dispatch.router.address', cols, limit=self.opts.limit)

        has_priority = False

        if show_date_id:
            self.display_datetime_router_id()

        if objects:
            first_row = objects[0]
            if first_row:
                if hasattr(first_row, 'priority'):
                    has_priority = True

        if has_priority:
            heads.append(Header("pri"))
        if self.opts.verbose:
            heads.append(Header("in-proc", Header.COMMAS))
        heads.append(Header("local", Header.COMMAS))
        heads.append(Header("remote", Header.COMMAS))
        heads.append(Header("in", Header.COMMAS))
        heads.append(Header("out", Header.COMMAS))
        heads.append(Header("thru", Header.COMMAS))
        heads.append(Header("fallback", Header.COMMAS))
        if self.opts.verbose:
            heads.append(Header("to-proc", Header.COMMAS))
            heads.append(Header("from-proc", Header.COMMAS))

        for addr in objects:
            row = []
            row.append(self._addr_class(addr.name))
            row.append(self._addr_text(addr.name))
            row.append(self._addr_phase(addr.name))
            row.append(addr.distribution)
            if has_priority:
                row.append(addr.priority if addr.priority >= 0 else "-")
            if self.opts.verbose:
                row.append(addr.inProcess)
            row.append(PlainNum(addr.containerCount) if addr.name[0] in 'CDEF' else PlainNum(addr.subscriberCount))
            row.append(PlainNum(addr.remoteCount))
            row.append(PlainNum(addr.deliveriesIngress))
            row.append(PlainNum(addr.deliveriesEgress))
            row.append(PlainNum(addr.deliveriesTransit))
            try:
                row.append(PlainNum(addr.deliveriesRedirectedToFallback))
            except:
                row.append("-")
            if self.opts.verbose:
                row.append(PlainNum(addr.deliveriesToContainer))
                row.append(PlainNum(addr.deliveriesFromContainer))
            rows.append(row)
        title = "Router Addresses"
        sorter = Sorter(heads, rows, 'addr', 0, True)
        dispRows = sorter.getSorted()
        disp.formattedTable(title, heads, dispRows)

    def displayAutolinks(self, show_date_id=True):
        disp = Display(prefix="  ", bodyFormat=self.bodyFormat)
        heads = []
        heads.append(Header("addr"))
        heads.append(Header("dir"))
        heads.append(Header("phs"))
        heads.append(Header("extAddr"))
        heads.append(Header("link"))
        heads.append(Header("status"))
        heads.append(Header("lastErr"))
        rows = []
        cols = ('address', 'direction', 'phase', 'externalAddress', 'linkRef', 'operStatus', 'lastError')

        objects = self.query('org.apache.qpid.dispatch.router.config.autoLink', cols, limit=self.opts.limit)

        if show_date_id:
            self.display_datetime_router_id()

        if not objects:
            print("AutoLinks")
            print("No AutoLinks found")
            return

        for al in objects:
            row = []
            row.append(al.address)
            row.append(al.direction)
            row.append(al.phase)
            row.append(al.externalAddress)
            row.append(al.linkRef)
            row.append(al.operStatus)
            row.append(al.lastError)
            rows.append(row)

        title = "AutoLinks"
        sorter = Sorter(heads, rows, 'addr', 0, True)
        dispRows = sorter.getSorted()
        disp.formattedTable(title, heads, dispRows)

    def displayLinkRoutes(self, show_date_id=True):
        disp = Display(prefix="  ", bodyFormat=self.bodyFormat)
        heads = []
        heads.append(Header("address"))
        heads.append(Header("dir"))
        heads.append(Header("distrib"))
        heads.append(Header("status"))
        rows = []
        cols = ('prefix', 'direction', 'distribution', 'operStatus', 'pattern', 'addExternalPrefix', 'delExternalPrefix')

        link_routes = self.query('org.apache.qpid.dispatch.router.config.linkRoute', cols, limit=self.opts.limit)

        have_add_del_prefix = False

        if not link_routes:
            if show_date_id:
                self.display_datetime_router_id()
            print("Link Routes")
            print("No Link Routes found")
            return

        if show_date_id:
            self.display_datetime_router_id()

        for link_route in link_routes:
            row = []
            row.append(link_route.prefix if link_route.prefix else link_route.pattern)
            row.append(link_route.direction)
            row.append(link_route.distribution)
            row.append(link_route.operStatus)
            try:
                if link_route.addExternalPrefix or link_route.delExternalPrefix:
                    row.append(link_route.addExternalPrefix)
                    row.append(link_route.delExternalPrefix)
                    have_add_del_prefix = True
            except KeyError:
                pass # added post 1.1.0
            rows.append(row)
        title = "Link Routes"
        if have_add_del_prefix:
            heads.append(Header("add-ext-prefix"))
            heads.append(Header("del-ext-prefix"))
        sorter = Sorter(heads, rows, 'address', 0, True)
        dispRows = sorter.getSorted()
        disp.formattedTable(title, heads, dispRows)

    def displayMemory(self, show_date_id=True):
        disp = Display(prefix="  ", bodyFormat=self.bodyFormat)
        heads = []
        heads.append(Header("type"))
        heads.append(Header("size", Header.COMMAS))
        heads.append(Header("batch"))
        heads.append(Header("thread-max", Header.COMMAS))
        heads.append(Header("total", Header.COMMAS))
        heads.append(Header("in-threads", Header.COMMAS))
        heads.append(Header("rebal-in", Header.COMMAS))
        heads.append(Header("rebal-out", Header.COMMAS))
        rows = []
        cols = ('identity', 'typeSize', 'transferBatchSize', 'localFreeListMax',
                'totalAllocFromHeap', 'heldByThreads', 'batchesRebalancedToThreads',
                'batchesRebalancedToGlobal')

        objects = self.query('org.apache.qpid.dispatch.allocator', cols)

        if show_date_id:
            self.display_datetime_router_id()

        pooled_total = 0
        for t in objects:
            row = []
            row.append(self._identity_clean(t.identity))
            row.append(PlainNum(t.typeSize))
            row.append(PlainNum(t.transferBatchSize))
            row.append(PlainNum(t.localFreeListMax))
            row.append(PlainNum(t.totalAllocFromHeap))
            row.append(PlainNum(t.heldByThreads))
            row.append(PlainNum(t.batchesRebalancedToThreads))
            row.append(PlainNum(t.batchesRebalancedToGlobal))
            rows.append(row)
            pooled_total += (t.typeSize * t.totalAllocFromHeap)
        if not rows:
            # router built w/o memory pools:
            print("No memory statistics available")
            return
        title = "Types"
        sorter = Sorter(heads, rows, 'type', 0, True)
        dispRows = sorter.getSorted()
        disp.formattedTable(title, heads, dispRows)

        # attempt to get the qdrouterd process memory usage
        # this may not be present on all platforms
        rows = []
        try:
            objects = self.query('org.apache.qpid.dispatch.router', ['memoryUsage'])
            mem = objects[0].memoryUsage
        except Exception:
            mem = None

        if mem is not None:
            hdr_format = Header.KiMiGi
            rows.append(mem)
        else:
            hdr_format = Header.NONE
            rows.append("-")

        rows.append(pooled_total)

        disp.formattedTable("\nSummary",
                            [Header("VmSize", hdr_format),
                             Header("Pooled", Header.KiMiGi)],
                            [rows])

    def displayLog(self):
        log = self.get_log(limit=self.opts.limit)
        for line in log:
            print("%s %s (%s) %s" % (ctime(line[5]), line[0], line[1], line[2]))

    def show_all(self, show_summary=True):
        if show_summary:
            # print the datetime and router id
            print(str(datetime.utcnow())  + " UTC")
            self.displayRouterId()
            print("")

        self.displayRouterLinks(show_date_id=False)
        print("")
        self.displayAddresses(show_date_id=False)
        print("")
        self.displayConnections(show_date_id=False)
        print("")
        self.displayAutolinks(show_date_id=False)
        print("")
        self.displayLinkRoutes(show_date_id=False)
        print("")
        self.displayGeneral(show_date_id=False)
        print("")
        self.displayMemory(show_date_id=False)
        print("")

    def has_nodes(self):
        all_nodes = super(BusManager, self).get_mgmt_nodes()
        has_nodes = True
        if all_nodes:
            if len(all_nodes) < 2:
                has_nodes = False
        else:
           has_nodes = False

        return has_nodes, all_nodes

    def has_nodes(self):
        all_nodes = super(BusManager, self).get_mgmt_nodes()
        has_nodes = True
        if all_nodes:
            if len(all_nodes) < 2:
                has_nodes = False
        else:
           has_nodes = False

        return has_nodes, all_nodes

    def display(self):
        has_nodes, nodes = self.has_nodes()
        if self.opts.all_routers and has_nodes:
            print(str(datetime.utcnow()) + " UTC")
            for node in nodes:
                super(BusManager, self).set_client(node[6:])
                parts = node.split("/")
                print ("Router ", parts[3])
                print("")
                if self.show.__name__ == 'show_all':
                    self.show(show_summary=False)
                else:
                    self.show(show_date_id=False)
                print("")
        else:
            self.show()

def run(argv):
    args = parse_args_qdstat(BusManager)
    bm = BusManager(args)
    try:
        bm.display()
    finally:
        bm.close()

if __name__ == "__main__":
    sys.exit(main(run))
