#!/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

try:
  from qpid_messaging import *
except:
  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 = str(eval(msg.content))
    except:
      content = traceback.format_exc()
    result = Message(content = 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()
