"""Associate a GitHub account with a Gittip account.

First we do the OAuth dance with GitHub. Once we've authenticated the user
against GitHub, we record them in our elsewhere table. This table contains
information for GitHub users whether or not they are explicit participants in
the Gittip community.

"""
from aspen import log, Response
from aspen import resources
from gittip import mixpanel
from gittip.elsewhere import ACTIONS, github
from gittip.participant import NeedConfirmation

# ========================== ^L

# Load GitHub user info.
user_info = github.oauth_dance(website, qs)

# Determine what we're supposed to do.
data = qs['data'].decode('base64').decode('UTF-8')
action, then = data.split(',', 1)
if action not in ACTIONS:
    raise Response(400)

# Make sure we have a GitHub login.
login = user_info.get('login')
if login is None:
    log(u"We got a user_info from GitHub with no login [%s, %s]"
        % (action, then))
    raise Response(400)

# Do something.
log(u"%s wants to %s" % (login, action))

account = github.GitHubAccount(user_info['id'], user_info)

if action == 'opt-in':      # opt in
    # set 'user' to give them a session :/
    user, newly_claimed = account.opt_in(login)
    if newly_claimed:
        mixpanel.alias_and_track(cookie, unicode(user.id))
elif action == 'connect':   # connect
    if user.ANON:
        raise Response(404)
    try:
        user.take_over(account)
    except NeedConfirmation, obstacles:

        # XXX Eep! Internal redirect! Really?!
        request.internally_redirected_from = request.fs
        request.fs = website.www_root + '/on/confirm.html'
        request.resource = resources.get(request)

        raise request.resource.respond(request)
else:                       # lock or unlock
    if then != login:

        # The user could spoof `then' to match their login, but the most they
        # can do is lock/unlock their own GitHub account in a convoluted way.

        then = u'/on/github/%s/lock-fail.html' % then

    else:

        # Associate the GitHub login with a randomly-named, unclaimed Gittip
        # participant.

        assert account.participant != login, login # sanity check

        account.set_is_locked(action == 'lock')

if then == u'':
    then = u'/%s/' % account.participant
if not then.startswith(u'/'):
    # Interpret it as a GitHub login.
    then = u'/on/github/%s/' % then
request.redirect(then)

# ========================== ^L text/plain
