#!/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(object):

    schema = QdSchema()

    def __init__(self, opts):
        self.opts = opts
        self.node = Node.connect(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 self.node.query(entity_type, attribute_names, count=limit).get_entities()

    def close(self):
        self.node.close()

    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("proto"))
        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(get(conn, 'role'))
            row.append(conn.protocol)
            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(PlainNum(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.node.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.node.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 = self.node.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 = self.node.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:
                self.node.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))
