import xchat
import sys
import re
__module_name__ = 'autoidentify' 
__module_version__ = '0.1' 
__module_description__ = 'Auto-identifyies with nickserv, auto-ops using chanserv, on the indymedia network' 

#FIXME: get some stuff from the preferences
#main_nick = xchat.get_prefs('irc_nick1')
#other_nicks = ( xchat.get_prefs('irc_nick2'), xchat.get_prefs('irc_nick3') )

main_nick = 'pabs'
other_nicks = ( 'pabs3', 'pabspabspabs' )
password = None
oper_password = None
oper_modes = '+bcdfknrswxyzl'
oper_modes = ''
operserv_password = None
sys.path.append('.xchat2')
sys.path.append('~/.xchat2')
from passwords import *
networks = ('indymedia.org', 'Indymedia')
nickserv = ':NickServ!NickServ@services.indymedia.org'
operserv = ':OperServ!OperServ@services.indymedia.org'
identified = 0
not_registered = re.compile( 'The nickname ..([-a-zA-Z0-9_|]*).. is not registered' )
get_old_nick = re.compile( ':([^!]*).*' )
debug_xchat = 0
debug_file = 0
user_oper = 1

info = []

# TODO
# on startup, store all the channels and perform appropriate stuff
# hook channel creations, lossage, op changes...


def log(msg):
	if debug_xchat:
		xchat.prnt( msg )
	if debug_file:
		f = open('autoidentify.log', 'ab')
		f.write(msg)
		f.write('\n')
		f.close()

def raw_cb(word, word_eol, userdata):
	global identified
	
	log( 'raw_cb: %s' % word_eol[0] )
		
def notice_cb(word, word_eol, userdata):
	global identified
	
	log( 'notice_cb: %s' % word )
	
	if word[0] != nickserv and word[0] != operserv:
		return xchat.EAT_NONE
		
	if xchat.get_info('network') not in networks:
		return xchat.EAT_NONE
		
	notice = word_eol[3][1:].strip()

	if word[0] == nickserv:
		if notice == 'This nickname is registered. Please choose a different nickname, or identify via \x02/msg NickServ identify <password>\x02.':
			log( 'notice_cb: Identifying'  )
			if not identified and password:
				xchat.command('nickserv identify %s' % password )
				identified = 0
		elif notice == 'You are now identified for \x02%s\x02.' % main_nick:
			log( 'notice_cb: Getting operator status' )
			identified = 1
			#xchat.command('msg chanserv op all')
			log( 'notice_cb: Identifying with OperServ' )
			if oper_password:
				log( 'notice_cb: Getting oper status' )
				xchat.command('oper %s %s' % (main_nick, oper_password) )
				xchat.command('mode %s %s' % (main_nick, oper_modes) )
		elif notice == '[%s] has been ghosted.' % main_nick:
			log( 'notice_cb: Switching to main nick (killed)' )
			xchat.command('nick %s' % main_nick )
		elif notice == '%s is not online.' % main_nick:
			log( 'notice_cb: Switching to main nick (not online)' )
			xchat.command('nick %s' % main_nick )
		elif notice == 'You are already logged in as \x02%s\x02.':
			log( 'notice_cb: already identified' )
			identified = 1
		else:
			try:
				nick = not_registered.match(notice).group(1)
			except:
				return xchat.EAT_NONE 
	
			# FIXME: check for the othernicks, with any number of underscores sfter them
			if nick in other_nicks and password:
				log( 'notice_cb: Killing main nick' )
				xchat.command('nickserv ghost %s %s' % (main_nick, password) )
	elif word[0] == operserv:
		if notice == 'You are now identified':
			#log( 'notice_cb: Getting op in #services' )
			#xchat.command('msg chanserv op #services' % (main_nick, oper_password) )
			#log( 'notice_cb: Joining #services' )
			#xchat.command('join #services')
			pass

	return xchat.EAT_NONE 

def twilight_cb(word, word_eol, userdata):
	log( 'twilight_cb: %s' % word )
	#log( 'twilight_cb: Joining #services' )
	#xchat.command('join #services')

# This is what we do when we notice our nick has changed
def nick_cb(word, word_eol, userdata):
	global identified
	
	log( 'nick_cb: %s' % word )

	if xchat.get_info('network') not in networks:
		return xchat.EAT_NONE

	identified = 0
	
	try:
		old_nick = get_old_nick.match(word[0]).group(1)
	except:
		return xchat.EAT_NONE 

	if old_nick != xchat.get_info('nick'):
		return xchat.EAT_NONE 

	new_nick = word[2][1:]

	identified = 0
	
	if new_nick == main_nick and password:
		log( 'nick_cb: Identifying' )
		xchat.command('nickserv identify %s' % password )

# This is what to do when we initally connect to a network
def welcome_cb(word, word_eol, userdata):
	global identified
	
	log( 'welcome_cb: %s' % word )
	log( 'welcome_cb: %s' % xchat.get_info('network') )

	if xchat.get_info('network') not in networks:
		return xchat.EAT_NONE

	log( 'welcome_cb: Welcomed' )

	nick = word[2]

	identified = 0

	if nick == main_nick:
		if password:
			log( 'welcome_cb: Identifying' )
			xchat.command('nickserv identify %s' % password )
	elif nick in other_nicks:
		if password:
			log( 'welcome_cb: Killing main nick' )
			xchat.command('nickserv ghost %s %s' % (main_nick, password) )
		
def ghost_cb(word, word_eol, userdata):
	if xchat.get_info('network') not in networks:
		return xchat.EAT_NONE

	if password:
		log( 'ghost_cb: Killing main nick' )
		xchat.command('nickserv ghost %s %s' % (main_nick, password) )

xchat.hook_server('NOTICE', notice_cb)
xchat.hook_server('NICK', nick_cb)
xchat.hook_server('001', welcome_cb)
xchat.hook_server('381', twilight_cb)
xchat.hook_command('GHOST', ghost_cb)

# Run this when we get loaded up
# So that we can resume control after being unloaded
channels = xchat.get_list('channels')
if channels:
	for channel in channels:
		log( 'on_load: loop' )
		if channel.context.get_info('network') in networks:
			log( 'on_load: Identifying' )
			if main_nick == channel.context.get_info('nick'):
				if not identified:
					if password:
						log( 'on_load: Identifying' )
						channel.context.command('nickserv identify %s' % password )
					break
			else:
				identified = 0
				log( 'on_load: Switching to main nick' )
				xchat.command('nick %s' % main_nick )
				break

log ('%s %s loaded' % (__module_name__, __module_version__))
