#!/usr/bin/env python

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

import os
from optparse import OptionGroup
import sys
import locale
import socket
import re
from time import ctime
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
from qpid_dispatch_internal.tools.command import connection_options, main, OptionParser, opts_ssl_domain, opts_url

def parse_args(argv):
    """ Set global variables for options, return arguments """

    usage = "%prog [options]"

    parser = OptionParser(usage=usage)

    parser.add_option_group(connection_options(parser))

    parser.add_option("-g", "--general", help="Show General Router Stats",  action="store_const", const="g",   dest="show")
    parser.add_option("-c", "--connections", help="Show Connections",       action="store_const", const="c",   dest="show")
    parser.add_option("-l", "--links", help="Show Router Links",            action="store_const", const="l",   dest="show")
    parser.add_option("-n", "--nodes", help="Show Router Nodes",            action="store_const", const="n",   dest="show")
    parser.add_option("-a", "--address", help="Show Router Addresses",      action="store_const", const="a",   dest="show")
    parser.add_option("-m", "--memory", help="Show Router Memory Stats",    action="store_const", const="m",   dest="show")
    parser.add_option("--autolinks", help="Show Auto Links",                action="store_const", const="autolinks",  dest="show")
    parser.add_option("--linkroutes", help="Show Link Routes",              action="store_const", const="linkroutes", dest="show")
    parser.add_option("-v", "--verbose", help="Show maximum detail",        action="store_true", dest="verbose")
    parser.add_option("--log", help="Show recent log entries", action="store_const", const="log", dest="show")
    parser.add_option("--limit", help="Limit number of log entries", type="int")

    opts, args = parser.parse_args(args=argv)

    if not opts.show:
        parser.error("You must specify one of these options: -g, -c, -l, -n, -a, -m, -h, --autolinks, --linkroutes, or --log.")

    return opts, args


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)))

    def query(self, entity_type):
        return super(BusManager, self).query(entity_type).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"
        if sasl == "EXTERNAL": sasl = "x.509"
        if sasl == "ANONYMOUS":
            return "anonymous-user"
        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 displayConnections(self):
        disp = Display(prefix="  ")
        heads = []
        heads.append(Header("host"))
        heads.append(Header("container"))
        heads.append(Header("role"))
        heads.append(Header("dir"))
        heads.append(Header("security"))
        heads.append(Header("authentication"))

        rows = []

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

        for conn in objects:
            row = []
            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))
            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] == 'C' : return "link-in"
        if addr[0] == 'D' : return "link-out"
        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):
        if not identity:
            return "-"
        pos = identity.find('/')
        if pos >= 0:
            return identity[pos + 1:]
        return identity

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

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

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

        router = objects[0]
        rows.append(('Mode',          router.mode))
        rows.append(('Area',          router.area))
        rows.append(('Router Id',     self._identity_clean(router.identity)))
        rows.append(('Address Count', router.addrCount))
        rows.append(('Link Count',    router.linkCount))
        rows.append(('Node Count',    router.nodeCount))

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

    def displayRouterLinks(self):
        disp = Display(prefix="  ")
        heads = []
        heads.append(Header("type"))
        heads.append(Header("dir"))
        heads.append(Header("id"))
        heads.append(Header("peer"))
        heads.append(Header("class"))
        heads.append(Header("addr"))
        heads.append(Header("phs"))
        heads.append(Header("cap"))
        heads.append(Header("undel"))
        heads.append(Header("unsettled"))
        heads.append(Header("deliveries"))
        heads.append(Header("admin"))
        heads.append(Header("oper"))
        if self.opts.verbose:
            heads.append(Header("name"))
        rows = []

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

        for link in objects:
            row = []
            row.append(link.linkType)
            row.append(link.linkDir)
            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)
            row.append(link.undeliveredCount)
            row.append(link.unsettledCount)
            row.append(link.deliveryCount)
            row.append(link.adminStatus)
            row.append(link.operStatus)
            if self.opts.verbose:
                row.append(link.linkName)
            rows.append(row)
        title = "Router Links"
        dispRows = rows
        disp.formattedTable(title, heads, dispRows)

    def displayRouterNodes(self):
        disp = Display(prefix="  ")
        heads = []
        heads.append(Header("router-id"))
        heads.append(Header("next-hop"))
        heads.append(Header("link"))
        if self.opts.verbose:
            heads.append(Header("neighbors"))
            heads.append(Header("valid-origins"))
        rows = []

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

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

            if self.opts.verbose:
                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"
            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):
        disp = Display(prefix="  ")
        heads = []
        heads.append(Header("class"))
        heads.append(Header("addr"))
        heads.append(Header("phs"))
        heads.append(Header("distrib"))
        heads.append(Header("in-proc", Header.COMMAS))
        heads.append(Header("local", Header.COMMAS))
        heads.append(Header("remote", Header.COMMAS))
        heads.append(Header("cntnr", Header.COMMAS))
        heads.append(Header("in", Header.COMMAS))
        heads.append(Header("out", Header.COMMAS))
        heads.append(Header("thru", Header.COMMAS))
        heads.append(Header("to-proc", Header.COMMAS))
        heads.append(Header("from-proc", Header.COMMAS))
        rows = []

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

        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)
            row.append(addr.inProcess)
            row.append(addr.subscriberCount)
            row.append(addr.remoteCount)
            row.append(addr.containerCount)
            row.append(addr.deliveriesIngress)
            row.append(addr.deliveriesEgress)
            row.append(addr.deliveriesTransit)
            row.append(addr.deliveriesToContainer)
            row.append(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):
        disp = Display(prefix="  ")
        heads = []
        heads.append(Header("addr"))
        heads.append(Header("dir"))
        heads.append(Header("phase"))
        heads.append(Header("link"))
        heads.append(Header("status"))
        heads.append(Header("lastErr"))
        rows = []

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

        for al in objects:
            row = []
            row.append(al.addr)
            row.append(al.dir)
            row.append(al.phase)
            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):
        disp = Display(prefix="  ")
        heads = []
        heads.append(Header("prefix"))
        heads.append(Header("dir"))
        heads.append(Header("distrib"))
        rows = []

        link_routes = self.query('org.apache.qpid.dispatch.router.config.linkRoute')

        for link_route in link_routes:
            row = []
            row.append(link_route.prefix)
            row.append(link_route.dir)
            row.append(link_route.distribution)
            rows.append(row)
        title = "Link Routes"
        sorter = Sorter(heads, rows, 'prefix', 0, True)
        dispRows = sorter.getSorted()
        disp.formattedTable(title, heads, dispRows)

    def displayMemory(self):
        disp = Display(prefix="  ")
        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 = []

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

        for t in objects:
            row = []
            row.append(self._identity_clean(t.identity))
            row.append(t.typeSize)
            row.append(t.transferBatchSize)
            row.append(t.localFreeListMax)
            row.append(t.totalAllocFromHeap)
            row.append(t.heldByThreads)
            row.append(t.batchesRebalancedToThreads)
            row.append(t.batchesRebalancedToGlobal)
            rows.append(row)
        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)

    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 displayMain(self, identitys, main):
        if   main == 'l': self.displayRouterLinks()
        elif main == 'n': self.displayRouterNodes()
        elif main == 'a': self.displayAddresses()
        elif main == 'm': self.displayMemory()
        elif main == 'g': self.displayGeneral()
        elif main == 'c': self.displayConnections()
        elif main == 'autolinks': self.displayAutolinks()
        elif main == 'linkroutes': self.displayLinkRoutes()
        elif main == 'log': self.displayLog()

    def display(self, identitys):
        self.displayMain(identitys, self.opts.show)

def run(argv):
    opts, args = parse_args(argv)
    if args[1:]:
        raise Exception("Unexpected arguments: %s" % " ".join(args[1:]))
    bm = BusManager(opts)
    try:
        bm.display(args)
    finally:
        bm.close()

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