#!/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', PlainNum(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 = "Memory Pools"
        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("\nMemory Summary",
                            [Header("VmSize", hdr_format),
                             Header("Pooled", Header.KiMiGi)],
                            [rows])


    def displayPolicy(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.policy')

        policy = objects[0]

        if show_date_id:
            self.display_datetime_router_id()

        rows.append(('Maximum Concurrent Connections', PlainNum(policy.maxConnections)))
        if 'maxMessageSize' in policy:
            rows.append(('Maximum Message Size',           PlainNum(policy.maxMessageSize)))
        rows.append(('Enable Vhost Policy',            policy.enableVhostPolicy))
        rows.append(('Enable Vhost Name Patterns',     policy.enableVhostNamePatterns))
        rows.append(('Policy Directory',               policy.policyDir if len(policy.policyDir) > 0 else '(nil)'))
        rows.append(('Default Vhost',                  policy.defaultVhost if len(policy.defaultVhost) > 0 else '(nil)'))
        disp.formattedTable("Policy Configuration", heads, rows)

        heads = []
        heads.append(Header("attr"))
        heads.append(Header("value"))
        rows = []

        rows.append(('Connections Processed',       PlainNum(policy.connectionsProcessed)))
        rows.append(('Connections Denied',          PlainNum(policy.connectionsDenied)))
        rows.append(('Connections Current',         PlainNum(policy.connectionsCurrent)))
        rows.append(('Links Denied',                PlainNum(policy.linksDenied)))
        if 'maxMessageSizeDenied' in policy:
            rows.append(('Maximum Message Size Denied', PlainNum(policy.maxMessageSizeDenied)))
        rows.append(('Total Denials',               PlainNum(policy.totalDenials)))

        disp.formattedTable("\nPolicy Status", heads, rows)

    def showNodefaultString(self, dict, key, schema):
        return dict[key] if key in dict else schema[key]['default'] if 'default' in schema[key] else '(nil)'

    def showNodefaultBool(self, dict, key, schema):
        return dict[key] if key in dict else schema[key]['default'] if 'default' in schema[key] else 'False'

    def showNodefaultInt(self, dict, key, schema):
        return PlainNum(dict[key]) if key in dict else PlainNum(schema[key]['default']) if 'default' in schema[key] else '(nil)'

    def displayVhosts(self, show_date_id=True):
        disp = Display(prefix="  ", bodyFormat=self.bodyFormat)

        vhosts = self.query('org.apache.qpid.dispatch.vhost')

        if len(vhosts) == 0:
            print("No Vhosts")
            return
        heads = []
        heads.append(Header("hostname"))
        heads.append(Header("maxConnections"))

        have_max_message_size = False
        if 'maxMessageSize' in vhosts[0]:
            have_max_message_size = True
            heads.append(Header('maxMessageSize'))

        heads.append(Header("maxConnectionsPerUser"))
        heads.append(Header("maxConnectionsPerHost"))
        heads.append(Header("allowUnknownUser"))
        heads.append(Header("groups"))

        rows = []
        for vhost in vhosts:
            row = []
            row.append(vhost.hostname)
            row.append(PlainNum(vhost.maxConnections))
            if have_max_message_size:
                row.append(PlainNum(vhost.maxMessageSize))
            row.append(PlainNum(vhost.maxConnectionsPerUser))
            row.append(PlainNum(vhost.maxConnectionsPerHost))
            row.append(vhost.allowUnknownUser)
            row.append(PlainNum(len(vhost.groups)))
            rows.append(tuple(row))

        disp.formattedTable("Vhosts", heads, rows)

    def displayVhostgroups(self, show_date_id=True):
        disp = Display(prefix="  ", bodyFormat=self.bodyFormat)

        vhosts = self.query('org.apache.qpid.dispatch.vhost')
        schema = self.get_schema()
        vg_schema = schema['entityTypes']['vhostUserGroupSettings']['attributes']

        if len(vhosts) == 0:
            print("No Vhosts")
            return
        # Create table for all vhosts and groups omitting
        # strings that are potentially 'very long'.
        heads = []
        heads.append(Header("vhost"))
        heads.append(Header("group"))
        heads.append(Header("maxConnectionsPerUser"))
        heads.append(Header("maxConnectionsPerHost"))

        have_max_message_size = False
        if 'maxMessageSize' in vhosts[0]:
            have_max_message_size = True
            heads.append(Header('maxMessageSize'))

        heads.append(Header("maxFrameSize"))
        heads.append(Header("maxSessionWindow"))
        heads.append(Header("maxSessions"))
        heads.append(Header("maxSenders"))
        heads.append(Header("maxReceivers"))
        heads.append(Header("allowDynamicSource"))
        heads.append(Header("allowAnonymousSender"))
        heads.append(Header("allowUserIdProxy"))
        heads.append(Header("allowWaypointLinks"))
        heads.append(Header("allowDynamicLinkRoutes"))
        heads.append(Header("allowAdminStatusUpdate"))
        heads.append(Header("allowFallbackLinks"))
        rows = []
        for vhost in vhosts:
            groups = vhost["groups"]
            if len(groups) > 0:
                for groupname in groups:
                    group = groups[groupname]
                    row = []
                    row.append(vhost.hostname)
                    row.append(groupname)
                    row.append(self.showNodefaultInt(group, "maxConnectionsPerUser", vg_schema))
                    row.append(self.showNodefaultInt(group, "maxConnectionsPerHost", vg_schema))
                    if have_max_message_size:
                        row.append(self.showNodefaultInt(group, "maxMessageSize", vg_schema))
                    row.append(self.showNodefaultInt(group, "maxFrameSize", vg_schema))
                    row.append(self.showNodefaultInt(group, "maxSessionWindow", vg_schema))
                    row.append(self.showNodefaultInt(group, "maxSessions", vg_schema))
                    row.append(self.showNodefaultInt(group, "maxSenders", vg_schema))
                    row.append(self.showNodefaultInt(group, "maxReceivers", vg_schema))
                    row.append(self.showNodefaultBool(group, "allowDynamicSource", vg_schema))
                    row.append(self.showNodefaultBool(group, "allowAnonymousSender", vg_schema))
                    row.append(self.showNodefaultBool(group, "allowUserIdProxy", vg_schema))
                    row.append(self.showNodefaultBool(group, "allowWaypointLinks", vg_schema))
                    row.append(self.showNodefaultBool(group, "allowDynamicLinkRoutes", vg_schema))
                    row.append(self.showNodefaultBool(group, "allowAdminStatusUpdate", vg_schema))
                    row.append(self.showNodefaultBool(group, "allowFallbackLinks", vg_schema))
                    rows.append(tuple(row))
        disp.formattedTable("Vhost Groups", heads, rows)

        # Create tables per vhost and per usergroup
        # showing only potentially lengthy strings.
        heads = []
        heads.append(Header("attr"))
        heads.append(Header("value"))

        for vhost in vhosts:
            groups = vhost["groups"]
            if len(groups) > 0:
                for groupname in groups:
                    group = groups[groupname]
                    rows = []
                    rows.append(("vhost",         vhost.hostname))
                    rows.append(("group",         groupname))
                    rows.append(("users",         self.showNodefaultString(group, "users", vg_schema)))
                    rows.append(("remoteHosts",   self.showNodefaultString(group, "remoteHosts", vg_schema)))
                    rows.append(("sources",       self.showNodefaultString(group, "sources", vg_schema)))
                    rows.append(("targets",       self.showNodefaultString(group, "targets", vg_schema)))
                    rows.append(("sourcePattern", self.showNodefaultString(group, "sourcePattern", vg_schema)))
                    rows.append(("targetPattern", self.showNodefaultString(group, "targetPattern", vg_schema)))
                    disp.formattedTable(("\nVhost '%s' UserGroup '%s'" % (vhost.hostname, groupname)), heads, rows)

    def displayVhoststats(self, show_date_id=True):
        disp = Display(prefix="  ", bodyFormat=self.bodyFormat)

        vstats = self.query('org.apache.qpid.dispatch.vhostStats')

        if len(vstats) == 0:
            print("No Vhost Stats")
            return
        heads = []
        heads.append(Header("hostname"))
        heads.append(Header("connectionsApproved"))
        heads.append(Header("connectionsDenied"))
        heads.append(Header("connectionsCurrent"))
        heads.append(Header("sessionDenied"))
        heads.append(Header("senderDenied"))
        heads.append(Header("receiverDenied"))
        have_max_message_size = False
        if 'maxMessageSizeDenied' in vstats[0]:
            have_max_message_size = True
            heads.append(Header("maxMessageSizeDenied"))
        rows = []

        for vstat in vstats:
            row = []
            row.append(vstat.hostname)
            row.append(PlainNum(vstat.connectionsApproved))
            row.append(PlainNum(vstat.connectionsDenied))
            row.append(PlainNum(vstat.connectionsCurrent))
            row.append(PlainNum(vstat.sessionDenied))
            row.append(PlainNum(vstat.senderDenied))
            row.append(PlainNum(vstat.receiverDenied))
            if have_max_message_size:
                row.append(PlainNum(vstat.maxMessageSizeDenied))
            rows.append(tuple(row))
        disp.formattedTable("Vhost Stats", heads, rows)

        heads = []
        heads.append(Header("vhost"))
        heads.append(Header("user"))
        heads.append(Header("remote hosts"))
        rows = []

        for vstat in vstats:
            ustates = vstat["perUserState"]
            if len(ustates) > 0:
                for ustate in ustates:
                    rows.append((
                        vstat.hostname,
                        ustate,
                        ustates[ustate]
                        ))
        disp.formattedTable("\nVhost User Stats", heads, 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("")
        self.displayPolicy(show_date_id=False)
        print("")
        self.displayVhosts(show_date_id=False)
        print("")
        # Groups is an ugly display. Show it only on demand.
        # self.displayVhostgroups(show_date_id=False)
        # print("")
        self.displayVhoststats(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))
