# plugs/birthday.py
#
#

""" this plugin allows for birthday data to be added and retrieved """

__copyright__ = 'this file is in the public domain'

from gozerbot.generic import getdaymonth, strtotime, elapsedstring, getwho\
, bdmonths 
from gozerbot.persist import Persist
from gozerbot.users import users
from gozerbot.commands import cmnds
from gozerbot.examples import examples
from gozerbot.datadir import datadir
from gozerbot.aliases import aliases
from gozerbot.plughelp import plughelp
import time, re, os

plughelp.add('birthday', 'birthday plugin')

birthdays = Persist(datadir + os.sep + 'birthdays')
if not birthdays.data:
    birthdays.data = {}

def size():
    """ return number of birthdays """
    return len(birthdays.data)

def handle_bdset(bot, ievent):
    """ bd-set <date> .. set birthday """
    try:
        what = ievent.args[0]
        if not re.search('\d*\d-\d*\d-\d\d\d\d', what):
            ievent.reply('i need a date in the format day-month-year')
            return
    except IndexError:
        ievent.missing('<date>')
        return
    # add data using username as index .. save to disk 
    user = users.getuser(ievent.userhost)
    birthdays.data[user.name] = what
    birthdays.save()
    ievent.reply('birthday set')

cmnds.add('bd-set', handle_bdset, 'USER', allowqueue=False)
examples.add('bd-set', 'bd-set <when> .. set birthday', 'bd-set 3-11-1967')
aliases.data['setbd'] = 'bd-set'
aliases.data['setjarig'] = 'bd-set'

def handle_bddel(bot, ievent):
    """ bd-del .. delete birthday """
    user = users.getuser(ievent.userhost)
    try:
        del birthdays.data[user.name]
    except KeyError:
        ievent.reply('no birthday known for %s' % ievent.nick)
        return
    birthdays.save()
    ievent.reply('birthday removed')

cmnds.add('bd-del', handle_bddel, 'USER')
examples.add('bd-del', 'delete birthday data', 'bd-del')
aliases.data['delbd'] = 'bd-del'
aliases.data['deljarig'] = 'bd-del'

def handle_bd(bot, ievent):
    """ bd .. show birthday of month (integer) or user """
    # check if arguments are given
    if not ievent.rest:    
        handle_checkbd(bot, ievent)
        return
    try:
        dummy = int(ievent.args[0]) # see if first argument is a number
        handle_checkbd2(bot, ievent)
        return
    except ValueError:
        who = ievent.args[0].lower()
    # get userhost of argument and try to find a user for it
    userhost = getwho(bot, who)
    if not userhost:
        ievent.reply("don't know userhost of %s" % who)
        return
    user = users.getuser(userhost)
    if not user:
        ievent.reply("can't find user for %s" % userhost)
        return
    try:
        # use username as index into the brithday dict
        birthday = birthdays.data[user.name] 
        ievent.reply('birthday of %s is %s' % (who, birthday))
    except KeyError:
        ievent.reply("i don't have birthday data for %s" % who)

cmnds.add('bd', handle_bd, ['USER', 'WEB'])
examples.add('bd', 'show birthdays for this month or show birthday of \
<nick>', '1) bd 2) bd test')
aliases.data['jarig'] = 'bd'

def handle_checkbd(bot, ievent):
    """ check birthdays for current month """
    (nowday, nowmonth) = getdaymonth(time.time())
    mstr = ""
    result = []
    # loop over birthday dict's items and see if we have birthdays today
    for i, j in birthdays.data.iteritems():
        btime = strtotime(j)
        if btime == None:
            continue
        (day, month) = getdaymonth(btime)
        if month == nowmonth:
            result.append((int(day), i, j))
            if day == nowday and month == nowmonth:
                ievent.reply("it's %s's birthday today!" % i)
    result.sort(lambda x, y: cmp(x[0], y[0]))
    for i in result:
        mstr += "%s: %s " % (i[1], i[2])
    # show birhtdays of this month
    if mstr:
        mstr = "birthdays this month = " + mstr
        ievent.reply(mstr)
    else:
        ievent.reply('no birthdays this month')

def handle_checkbd2(bot, ievent):
    """ show birthdays in month (by number) """
    try:
        monthnr = int(ievent.args[0])
        if monthnr < 1 or monthnr > 12:
            ievent.reply("number must be between 1 and 12")
            return
    except IndexError:
        return
    except ValueError:
        return
    mstr = ""
    result = []
    # loop over items in birthday dict, check if its in the month given
    for i, j in birthdays.data.iteritems():
        btime = strtotime(j)
        if btime == None:
            continue
        (day, month) = getdaymonth(btime)
        if month == bdmonths[monthnr]:
            result.append((int(day), i, j))
    result.sort(lambda x, y: cmp(x[0], y[0]))
    for i in result:
        mstr += "%s: %s " % (i[1], i[2])
    if mstr:
        mstr = "birthdays in %s = " % bdmonths[monthnr] + mstr
        ievent.reply(mstr)
    else:
        ievent.reply('no birthdays found for %s' % bdmonths[monthnr])

def handle_age(bot, ievent):
    """ age <nick> .. show age of user """
    try:
        nick = ievent.args[0].lower()
    except IndexError:
        ievent.missing('<nick>')
        return
    # get username of nick
    userhost = getwho(bot, nick)
    if not userhost:
        ievent.reply("don't know userhost of %s" % nick)
        return
    user = users.getuser(userhost)
    if not user:
        ievent.reply("can't find user for %s" % userhost)
        return
    # fetch birthday data
    try:
        birthday = birthdays.data[user.name]
    except KeyError:
        ievent.reply("can't find birthday data for %s" % nick)
        return
    btime = strtotime(birthday)
    if btime == None:
        ievent.reply("can't make a date out of %s" % birthday)
        return
    # calculate time elapsed
    age = int(time.time()) - int(btime)
    ievent.reply("age of %s is %s" % (nick, elapsedstring(age, ywd=True)))

cmnds.add('age', handle_age, ['USER', 'WEB'], allowqueue=False)
examples.add('age', 'age <nick> .. show how old <nick> is', 'age test')
aliases.data['oud'] = 'age'
