#!/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 os
import itertools
import string
import time
import urllib
import socket
from hashlib import md5
import getpass
import pprint
from collections import defaultdict

from gssapi import Credentials
from gssapi.exceptions import GSSError
from requests_gssapi import HTTPSPNEGOAuth
from tahrir_api.dbapi import TahrirDatabase
import transaction
import requests

import logging
log = logging.getLogger()
logging.basicConfig(level=logging.INFO)
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


def get_http_client():
    os.environ["KRB5_CLIENT_KTNAME"] = fm_config.get("keytab")
    try:
        creds = Credentials(usage="initiate")
    except GSSError as e:
        log.error("GSSError trying to authenticate with Kerberos", e)
    gssapi_auth = HTTPSPNEGOAuth(opportunistic_auth=True, creds=creds)
    session = requests.Session()
    session.auth = gssapi_auth
    return session


def get_fas_groupings(fas_credentials, lookup, **config):
    results = defaultdict(list)
    membership_types = ("members", "sponsors")
    http_client = get_http_client()
    for group_name, badge_id in lookup.iteritems():
        # This is the main check.
        for membership_type in membership_types:
            url = "%sgroups/%s/%s/" % (
                fm_config['fasjson_base_url'],
                group_name,
                membership_type
            )
            response = http_client.get(url)
            if not response.ok:
                continue
            for user in response.json()["result"]:
                username = user["username"]
                results[group_name].append(username)

                # Beyond the main check, here is a special check for the sponsors of the packager and ambassadors groups
                if membership_type != "sponsors":
                    continue
                if group_name == "packager":
                    results["sponsors"].append(username)
                elif group_name == "ambassadors":
                    results["ambassadors_sponsors"].append(username)

    return results


def main():
    d = {}
    print "fascache.db code is commented out --  querying fas."

    # A mapping of fas groups to badge ids
    mapping = {
        '3d-printing-sig': '3d-printing-sig-member',
        'cla_done': 'involvement',
        'advocates': 'fedora-advocate',
        'ambassadors': 'ambassador',
        'ambassadors_sponsors': 'ambassadors-sponsor',
        'commops': 'commops-superstar',
        'council': 'council-member',
        'designteam': 'pixel-ninja',
        'dotnet-team': 'dotnet-sig-member',
        'fedora-hams': 'amateur-radio-sig-member',
        'fi-apprentice': 'no-longer-a-ronin',
        'gitfedora-web': 'rock-the-web!',
        'git-fedora-electronic-lab': 'fel-member',
        'iot': 'iot-working-group-member',
        'irc-support-operators':
        'your-call-may-be-monitored-for-quality-assurance',
        'kde-sig': 'kde-sig',
        'lxqt-sig': 'lxqt-sig-member',
        'marketing': 'called-to-action',
        'mindshare': 'meeting-of-the-minds',
        'modularity-wg': 'modularity-wg-member',
        'neuro-sig': 'neurofedora-sig-member',
        'provenpackager': 'proven-packager',
        'proventesters': 'proven-tester',
        'robotics-sig': 'domo-arigato',
        'ruby-sig': 'ruby-sig-member',
        'security-team': 'security-team',
        'sponsors': 'packager-sponsor',
        'summer-coding': 'summer-coder',
        'sysadmin-main': 'trust-me,-i-know-what-i-am-doing',
        'sysadmin-badges': 'inside-job',
        'videos': 'videographer',
    }

    # First, some validation that the badge ids actually exist.
    for fas_group, badge_id in mapping.items():
        badge = tahrir.get_badge(badge_id=badge_id)
        if not badge:
            raise ValueError("%r is not a valid badge id" % badge_id)

    # Then, do a long query against FAS for our candidates.
    results = get_fas_groupings(fas_credentials=fm_config['fas_credentials'],
                                lookup=mapping)

    for fas_group, members in results.iteritems():
        print fas_group, "had", len(members), "members for", mapping[fas_group]

    for fas_group, members in results.iteritems():
        print "processing", fas_group
        print "======================"
        badge = tahrir.get_badge(badge_id=mapping[fas_group])
        hit_em_up(badge, members)


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

        if not user:
            continue

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

        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()
