#!/usr/bin/env python

"""
Pegasus utility for sending workflow notifications over jabber

"""

##
#  Copyright 2007-2011 University Of Southern California
#
#  Licensed 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.
##


__author__ = "Mats Rynge <rynge@isi.edu>"


import warnings
warnings.simplefilter("ignore")

import os
import sys
import time
import optparse

# --- functions -----------------------------------------------------------------------


def usage(parser):
    print ""
    print "Usage: This tool is used by pegasus-monitord to send event notifications"
    print "over jabber. A set of environment variables are expected to be set:"
    print "   PEGASUS_EVENT"
    print "   PEGASUS_EVENT_TIMESTAMP_ISO"
    print "   PEGASUS_JOBID"
    print "   PEGASUS_STATUS (only for end events)"
    print ""
    parser.print_help()
    print ""
    myexit(1)
    

def validate_env_var(key):
    if not key in os.environ:
        raise RuntimeError(key + " is not defined in the current environment")


def myexit(rc):
    """
    system exit without a stack trace - silly python
    """
    try:
        sys.exit(rc)
    except SystemExit:
        sys.exit(rc)


# --- main ----------------------------------------------------------------------------

try:
    import xmpp
except ImportError:
    print >> sys.stderr, "The Python xmpp library is missing. On RHEL and Debian based systems,"
    print >> sys.stderr, "please install the python-xmpp package."
    myexit(1)


# Configure command line option parser
parser = optparse.OptionParser()
parser.add_option("-i", "--jabberid", action = "store", dest = "jabber_id",
                  help = "Your jabber id. Example: user@jabberhost.com")
parser.add_option("-p", "--password", action = "store", dest = "password",
                  help = "Your jabber password")
parser.add_option("-s", "--host", action = "store", dest = "host",
                  help = "Jabber host, if different from the host in your jabber id." \
                       +  " For Google talk, set this to talk.google.com")
parser.add_option("-r", "--recipient", action = "store", dest = "recipient",
                  help = "Jabber id of the recipient. Not necessary if you want to send to your own jabber id")

# Parse command line options
(options, args) = parser.parse_args()

if options.jabber_id == None:
    print >> sys.stderr, "You have to provide a jabber id"
    usage(parser)
jabber_id = options.jabber_id
if options.password == None:
    print >> sys.stderr, "You have to provide a password"
    usage(parser)
password = options.password
host = options.host
recipient = options.recipient
if recipient == None:
    recipient = jabber_id

try:
    validate_env_var("PEGASUS_EVENT")
    validate_env_var("PEGASUS_EVENT_TIMESTAMP_ISO")
    validate_env_var("PEGASUS_JOBID")
except RuntimeError, err:
    print >> sys.stderr, err
    usage(parser)


msg = " === Pegasus Workflow Event ===\n" \
    + "Time:   " + os.environ['PEGASUS_EVENT_TIMESTAMP_ISO'] + "\n" \
    + "Job id: " + os.environ['PEGASUS_JOBID'] + "\n" \
    + "Event:  " + os.environ['PEGASUS_EVENT'] + "\n"
    
if 'PEGASUS_STATUS' in os.environ:
    msg = msg \
        + "Status: " + os.environ['PEGASUS_STATUS'] + "\n"

jid = xmpp.protocol.JID(jabber_id)
cl = xmpp.Client(jid.getDomain(), debug = [])

if host == None:
    host = jid.getDomain()

con = cl.connect((host, 5223), use_srv=False)
if not con:
    con = cl.connect((host, 5222), use_srv=False)
    if not con:
        print >> sys.stderr, "Unable to connect to " + host
        myexit(1)

auth = cl.auth(jid.getNode(), password, resource = "Pegasus")
if not auth:
    print >> sys.stderr, "Unable to authenticate with " + host
    myexit(1)

mid = cl.send(xmpp.protocol.Message(recipient, msg))

time.sleep(1)   # some servers will not send the message if you disconnect immediately after sending
cl.disconnect()
myexit(0)
