#!/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 optparse, sys, traceback
from qpid.messaging import *
from qpid.util import URL
from subprocess import Popen, STDOUT, PIPE
from qpid.log import enable, DEBUG, WARN

parser = optparse.OptionParser(usage="usage: %prog [options] ADDRESS ...",
                               description="handle requests from the supplied address.")
parser.add_option("-b", "--broker", default="localhost",
                  help="connect to specified BROKER (default %default)")
parser.add_option("-r", "--reconnect", action="store_true",
                  help="enable auto reconnect")
parser.add_option("-i", "--reconnect-interval", type="float", default=3,
                  help="interval between reconnect attempts")
parser.add_option("-l", "--reconnect-limit", type="int",
                  help="maximum number of reconnect attempts")
parser.add_option("-v", dest="verbose", action="store_true",
                  help="enable logging")

opts, args = parser.parse_args()

if opts.verbose:
  enable("qpid", DEBUG)
else:
  enable("qpid", WARN)

if args:
  addr = args.pop(0)
else:
  parser.error("address is required")

conn = Connection(opts.broker,
                  reconnect=opts.reconnect,
                  reconnect_interval=opts.reconnect_interval,
                  reconnect_limit=opts.reconnect_limit)
def dispatch(msg):
  msg_type = msg.properties.get("type")
  if msg_type == "shell":
    proc = Popen(msg.content, shell=True, stderr=STDOUT, stdin=PIPE, stdout=PIPE)
    output, _ = proc.communicate()
    result = Message(output)
    result.properties["exit"] = proc.returncode
  elif msg_type == "eval":
    try:
      content = eval(msg.content)
    except:
      content = traceback.format_exc()
    result = Message(content)
  else:
    result = Message("unrecognized message type: %s" % msg_type)
  return result

try:
  conn.open()
  ssn = conn.session()
  rcv = ssn.receiver(addr)

  while True:
    msg = rcv.fetch()
    response = dispatch(msg)
    snd = None
    try:
      snd = ssn.sender(msg.reply_to)
      snd.send(response)
    except SendError, e:
      print e
    if snd is not None:
      snd.close()
    ssn.acknowledge()
except ReceiverError, e:
  print e
except KeyboardInterrupt:
  pass

conn.close()
