#!/usr/bin/env python

import __main__
# This is going to require sqlalchemy 0.8 sooner than later.
__main__.__requires__ = __requires__ = ["tahrir-api", "sqlalchemy>=0.7"];
import pkg_resources
pkg_resources.require(__requires__)

import datetime
import time
import urllib
import socket

from tahrir_api.dbapi import TahrirDatabase
import transaction

_fas_cache = {}

import logging
log = logging.getLogger()
logging.basicConfig()
import fedora.client.fas2

import fedmsg
import fedmsg.config

fm_config = fedmsg.config.load_config()
fm_config['cert_prefix'] = 'fedbadges'
fm_config['name'] = 'relay_inbound'
fm_config['active'] = True
fedmsg.init(**fm_config)

import fedbadges.utils


#a simple listcomp to generate a lists of searchterms
#allows us to break the fas userlist down to smaller chunks
#so the cron job doesn't hang
def get_fas_searchterm():
    ast = "*"
    alpha = map(chr, range(97, 123))
    searchterms = [ term_str + ast for term_str in alpha ]
    return searchterms


def get_fas_userlist(fas_credentials):
    creds = fas_credentials

    fasclient = fedora.client.fas2.AccountSystem(
        username=creds['username'],
        password=creds['password'],
    )

    timeout
    timeout = socket.getdefaulttimeout()
    socket.setdefaulttimeout(600)
    searchterm = get_fas_searchterms()
    for search_elem in searchterm:
        try:
            log.info("Downloading FAS cache")
            request = fasclient.send_request('/user/list',
                                         req_params={'search': search_elem},
                                         auth=True)
            fas_userlist.update(request)
        finally:
            socket.setdefaulttimeout(timeout)

    # We don't actually check for CLA+1, just "2 groups"
    return [p for p in fas_userlist['people'] if len(p.memberships) > 1]


def main():
    now = datetime.datetime.utcnow()
    year = datetime.timedelta(days=365.5)
    search_terms = get_fas_searchterms() 
    mapping = {
        'egg': year * 1,
        'embryo': year * 2,
        'tadpole': year * 3,
        'tadpole-with-legs': year * 5,
        'froglet': year * 7,
        'adult-frog': year * 10,
    }

    # First, some validation that the badge ids actually exist.
    for badge_id, delta in mapping.items():
        badge = tahrir.get_badge(badge_id=badge_id)
        assert(badge.id)

    # Then, do a long query against FAS for our candidates.
    # looping over a list of search terms allows us to work around the socket timeout
    results = get_fas_userlist(fas_credentials=fm_config['fas_credentials'])

    for badge_id, delta in mapping.items():
        badge = tahrir.get_badge(badge_id=badge_id)
        for person in results:
            creation = datetime.datetime.strptime(
               person.creation.split('.')[0], '%Y-%m-%d %H:%M:%S')
            if now - creation > delta:
                hit_em_up(badge, person)


def hit_em_up(badge, fas_user):
    email = fas_user.username + "@fedoraproject.org"
    user = tahrir.get_person(email)

    if not user:
        return

    if tahrir.assertion_exists(badge.id, email):
        print email, "already has", badge.id, "skipping."
        return

    time.sleep(1)
    print "awarding", badge.id, "to", email
    try:
        transaction.begin()
        tahrir.add_assertion(badge.id, email, None)
        transaction.commit()
    except Exception as e:
        transaction.abort()
        print "Failure:", e


if __name__ == '__main__':
    uri = fm_config['badges_global']['database_uri']
    tahrir = TahrirDatabase(
        uri,
        notification_callback=fedbadges.utils.notification_callback,
    )
    main()
