#!/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
import optparse
from optparse import IndentedHelpFormatter
import sys
import socket
from time import time, strftime, gmtime, sleep
from qmf.console import Console, Session


class EventConsole(Console):
  def event(self, broker, event):
    print event
    sys.stdout.flush()

  def brokerConnected(self, broker):
    print strftime("%c", gmtime(time())), "NOTIC qpid-printevents:brokerConnected broker=%s" % broker.getUrl()
    sys.stdout.flush()

  def brokerConnectionFailed(self, broker):
    print strftime("%c", gmtime(time())), "NOTIC qpid-printevents:brokerConnectionFailed broker=%s %s" % (broker.getUrl(), str(broker.conn_exc))
    sys.stdout.flush()

  def brokerDisconnected(self, broker):
    print strftime("%c", gmtime(time())), "NOTIC qpid-printevents:brokerDisconnected broker=%s" % broker.getUrl()
    sys.stdout.flush()

class JHelpFormatter(IndentedHelpFormatter):
    """Format usage and description without stripping newlines from usage strings
    """

    def format_usage(self, usage):
        return usage

    def format_description(self, description):
        if description:
            return description + "\n"
        else:
            return ""

_usage = "%prog [options] [broker-addr]..."

_description = \
"""
Collect and print events from one or more Qpid message brokers.

If no broker-addr is supplied, %prog connects to 'localhost:5672'.

[broker-addr] syntax:

          [username/password@] hostname
          ip-address [:<port>]

Examples:

$ %prog localhost:5672
$ %prog 10.1.1.7:10000
$ %prog guest/guest@broker-host:10000
"""

def main(argv=None):
  p = optparse.OptionParser(usage=_usage, description=_description, formatter=JHelpFormatter())
  p.add_option("--heartbeats", action="store_true", default=False, help="Use heartbeats.")
  p.add_option("--sasl-mechanism", action="store", type="string", metavar="<mech>", help="SASL mechanism for authentication (e.g. EXTERNAL, ANONYMOUS, PLAIN, CRAM-MD, DIGEST-MD5, GSSAPI). SASL automatically picks the most secure available mechanism - use this option to override.")

  options, arguments = p.parse_args(args=argv)
  if len(arguments) == 0:
    arguments.append("localhost")

  console = EventConsole()
  session = Session(console, rcvObjects=False, rcvHeartbeats=options.heartbeats, manageConnections=True)
  brokers = []
  try:
    try:
      for host in arguments:
        brokers.append(session.addBroker(host, None, options.sasl_mechanism))

        while (True):
          sleep(10)

    except KeyboardInterrupt:
        print
        return 0

    except Exception, e:
        print "Failed: %s - %s" % (e.__class__.__name__, e)
        return 1
  finally:
    while len(brokers):
      b = brokers.pop()
      session.delBroker(b)

if __name__ == '__main__':
  sys.exit(main())
