#!/usr/bin/python
# -*- encoding: latin-1 -*-

import pyxmpp.all
import pyxmpp.jabber.all
import os, time

config = dict(
    jid='bbolli@swissjabber.ch/pybot',
    pwd='*********',
    srv='swissjabber.ch',
    def_dest='bbolli@swissjabber.ch',
)


class SimpleClient(pyxmpp.jabber.Client):

    def roster_updated(self, item=None):
	if item is not None:
	    print 'roster update:', item.as_xml()

    def stream_state_changed(self, state, arg):
	print 'stream state:', state, repr(arg)
#	if state == 'authorized':
#	    self.sendmsg()

    def session_started(self):
	pyxmpp.jabber.Client.session_started(self)
	self.cmd_map = {
	    'quit': self.quit,
	    'start': self.start,
	    'stop': self.stop,
	}
	self.handler = None
	self.stream.set_message_handler('normal', self.on_message)
	self.stream.set_presence_handler('available', self.on_presence)

    def on_message(self, stanza):
	body = stanza.get_body()
	#print '%s: %s' % (stanza.get_from_jid(), body)
	if ' ' in body:
	    cmd, arg = body.split(None, 1)
	else:
	    cmd, arg = body, ''
	cmd = cmd.lower()
	if cmd in self.cmd_map:
	    self.cmd_map[cmd](arg)
	else:
	    self.sendmsg('msg: ' + body)
	return True

    def on_presence(self, presence):
	show = presence.get_show()
	status = presence.get_status()
	if not show and not status:
	    s = 'available'
	elif show and status:
	    s = '%s (%s)' % (show, status)
	else:
	    s = show or status
	self.sendmsg('%s: %s' % (presence.get_from().as_unicode(), s))

    def start(self, arg):
	self.handler = FileLogger(self, arg)

    def stop(self, arg=''):
	self.handler = None

    def quit(self, arg):
	self.stop()
	self.disconnect()

    def sendmsg(self, msg=None):
	if msg is None: msg = self.msg
	m = pyxmpp.Message(from_jid=self.jid, to_jid=self.dest, body=msg)
	m.set_type('chat')
	#print m.get_node()
	self.stream.send(m)

    def idle(self):
	pyxmpp.jabber.Client.idle(self)
	if self.handler:
	    self.handler.run()


class FileLogger:

    def __init__(self, client, fname):
	self.client = client
	self.send = client.sendmsg
	if not fname: fname = 'syslog'
	self.fname = '/var/log/' + fname
	try:
	    self.fp = open(self.fname, 'r', 1)	# line buffered
	    self.fp.seek(0, 2)	# seek to EOF
	    self.send('Logging %s...' % self.fname)
	except IOError:
	    self.send('Error opening ' + self.fname)
	    self.fp = None

    def __del__(self):
	if self.fp: self.fp.close()
	self.send('Stopped %s.' % self.fname)

    def run(self):
	if not self.fp: return
	for line in [l.strip() for l in self.fp.readlines()]:
	    if line:	# and '/CRON' not in line:
		self.send(line)
	

if __name__ == '__main__':
    import sys, logging

    l = logging.Logger.root
    l.addHandler(logging.StreamHandler())
    l.setLevel(logging.INFO)

    if len(sys.argv) == 1:
	sys.argv.append(config['def_dest'])
    elif sys.argv[1] in ('-h', '-help', '--help'):
	print >>sys.stderr, 'Usage: sabber [to_jid] [message]; uses stdin if no message'
	sys.exit(1)
    if len(sys.argv) == 2:
	sys.argv.append(sys.stdin.read())

    me = pyxmpp.JID(config['jid'])
    cl = SimpleClient(me, config['pwd'], config['srv'], disco_name="sabber", disco_type='bot')
    cl.dest = pyxmpp.JID(sys.argv[1])
    cl.msg = ' '.join(sys.argv[2:]).strip()
    cl.connect()
    #print cl.disco_identity
    #print cl.disco_info.as_xml()
    #print cl.disco_items.as_xml()

    try:
	cl.loop()
    except KeyboardInterrupt:
	pass

    cl.disconnect()