#!/usr/bin/python
import sys
import urllib
import time
from xml.dom import minidom
from tuxisalive.api import *

def main(xmlPath):
	# load the inital settings that we will use to compare against
	projects = []

	dom = minidom.parse(urllib.urlopen(xmlPath))
	for node in dom.getElementsByTagName('Project'):
		projects.append({
			'name': node.getAttribute('name'),
			'lastBuildStatus': node.getAttribute('lastBuildStatus'),
			'lastBuildTime': node.getAttribute('lastBuildTime')
		})

	# start a loop that will check for a build event every 10 seconds
	while True:
		try:
			dom = minidom.parse(urllib.urlopen(xmlPath))
			new_projects = []
			for node in dom.getElementsByTagName('Project'):
				new_projects.append({
					'name': node.getAttribute('name'),
					'lastBuildStatus': node.getAttribute('lastBuildStatus'),
					'lastBuildTime': node.getAttribute('lastBuildTime')
				})
				for project in new_projects:
					# check to see if the project is in the current list
					projectFound = False
					for p in projects:
						if p['name'] == project['name']:
							projectFound = True
							# check the status of the project against the old status
							# ignore if the old status is failed
							if (p['lastBuildStatus'] != 'Failure') and (project['lastBuildStatus'] == 'Failure'):
								display_message_fail(project)
							if (p['lastBuildStatus'] == 'Failure') and (project['lastBuildStatus'] == 'Success'):
								display_message_success(project)
							if (project['lastBuildStatus'] == 'Success') and (project['lastBuildTime']  != p['lastBuildTime'] ):
								display_message_success_build_again(project)

							# reset the project status
							p['lastBuildStatus'] = project['lastBuildStatus']
							p['lastBuildTime'] = project['lastBuildTime']
					if not projectFound:
						projects.append(project)
						display_message_newproject(project)
			time.sleep(10)
		except KeyboardInterrupt:
			# exit time
			break

def display_message_fail(project):
	msg = 'Someone has broken the %s build' % (project['name'])
	speakPhrase(msg)

def display_message_success(project):
	msg = '%s is now fixed' % (project['name'])
	speakPhrase(msg)

def display_message_new(project):
	msg = '%s has been added to cruise control' % (project['name'])
	speakPhrase(msg)

def display_message_success_build_again(project):
	msg = '%s has successfuly been built' % (project['name'])
	speakPhrase(msg)

def speakPhrase(msg):
	tux.mouth.open()

	tux.tts.setLocutor("Lucy")
	tux.tts.speak(msg.encode('utf-8'));
	print msg
	tux.flippers.on(4)

	tux.mouth.close()

def tuxConnect():
    """ Wait connected """
    tux.server.autoConnect(CLIENT_LEVEL_RESTRICTED, 'TuxPidgin', 'NONE')    
    if tux.server.waitConnected(10.0):
        if tux.dongle.waitConnected(10.0):  
            if tux.radio.waitConnected(10.0):
                return True
            else:
                print "radio not connected"
                return False
        else:
            print "radio not connected"
            return False
    else:
        print "server not connected"
        return False

def printUsage():
	print "ccnet.py [url]"
	print "\turl - Url of CruiseControl.NET"
	print "\t\t eg. http://localhost/ccnet/XmlServerReport.aspx"

if __name__ == "__main__":
	if len(sys.argv) == 2:

		tgp_ip = "127.0.0.1"
		tgp_port = 270
		tux = TuxAPI(tgp_ip, tgp_port)
		if not tuxConnect():
		    sys.exit(1)
		tux.tts.setEncoding("utf-8")

		speakPhrase("Starting Build Bot")
		main(sys.argv[1])
		speakPhrase("Stopping Build Bot")
		tux.server.disconnect()
		tux.destroy()
		sys.exit(0)
	else:
		printUsage()

