#!/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.schema.qd_schema 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_sasl, \
        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),
                            sasl=opts_sasl(self.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("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"))

        rows = []

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

        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))
            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, 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 = []
        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, router.routerId)))

        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("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"))
        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.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)
            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("cost"))
            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.id)
            if node.nextHop != None:
                row.append(node.nextHop)
                row.append('-')
            else:
                row.append('-')
                row.append(node.routerLink)

            if self.opts.verbose:
                row.append(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"
            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("phs"))
        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"))
        heads.append(Header("status"))
        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)
            row.append(link_route.operStatus)
            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))
