import elixir
import logging
from openid.consumer.consumer import Consumer
from openid.extensions.sreg import SRegRequest, SRegResponse
from openid.store.filestore import FileOpenIDStore
from sqlalchemy.orm.exc import NoResultFound

from pylons import request, response, session, tmpl_context as c
from pylons.controllers.util import abort, redirect_to
from routes import url_for, request_config

from floof.lib.base import BaseController, render
from floof.model.users import IdentityURL, User

log = logging.getLogger(__name__)

class AccountController(BaseController):

    openid_store = FileOpenIDStore('/var/tmp')

    def login(self):
        return render('/login.mako')

    def login_begin(self):
        """Step one of logging in with OpenID; we redirect to the provider"""

        cons = Consumer(session=session, store=self.openid_store)
        auth_request = cons.begin(request.params['identity_url'])
        sreg_req = SRegRequest(optional=['nickname', 'email', 'dob', 'gender',
                                         'country', 'language', 'timezone'])
        auth_request.addExtension(sreg_req)

        host = request.headers['host']
        protocol = request_config().protocol
        return_url = url_for(host=host, controller='account', action='login_finish')
        new_url = auth_request.redirectURL(return_to=return_url,
                                           realm=protocol + '://' + host)
        redirect_to(new_url)

    def login_finish(self):
        """Step two of logging in; the OpenID provider redirects back here."""

        cons = Consumer(session=session, store=self.openid_store)
        host = request.headers['host']
        return_url = url_for(host=host, controller='account', action='login_finish')
        res = cons.complete(request.params, return_url)

        if res.status != 'success':
            return 'Error!  %s' % res.message

        try:
            # Grab an existing user record, if one exists
            q = User.query.filter(User.identity_urls.any(url=res.identity_url))
            user = q.one()
        except NoResultFound:
            # Try to pull a name out of the SReg response
            sreg_res = SRegResponse.fromSuccessResponse(res)
            try:
                username = unicode(sreg_res['nickname'])
            except:
                username = u'Anonymous'

            # Create db records
            user = User(name=username)
            identity_url = IdentityURL(url=res.identity_url)
            user.identity_urls.append(identity_url)
            elixir.session.commit()

        # Remember who's logged in, and we're good to go
        session['user_id'] = user.id
        session.save()

        # XXX send me where I came from
        redirect_to('/')
