#-*- coding: utf-8 -*-
u"""Declares a user action for granting access to a Twitter account.

.. moduleauthor:: Martí Congost <marti.congost@whads.com>
"""
from oauth2 import Client, Consumer, Token
import cherrypy
from urllib import urlopen, quote_plus
from urlparse import parse_qsl
from simplejson import loads
from cocktail.persistence import datastore
from cocktail.translations import translations
from cocktail.controllers import Location, session
from woost.controllers.notifications import Notification
from woost.controllers.backoffice.useractions import UserAction
from woost.extensions.twitterpublication.exceptions import TwitterAPIError
from woost.extensions.twitterpublication.twitterpublicationtarget \
    import TwitterPublicationTarget


class TwitterAuthUserAction(UserAction):

    content_type = TwitterPublicationTarget

    included = frozenset(["item_buttons"])
    excluded = frozenset(["new_item"])
    min = 1
    max = 1

    def invoke(self, controller, selection):

        target = selection[0]
        consumer = Consumer(target.app_id, target.app_secret)

        def request(client, *args, **kwargs):
            response, body = client.request(*args, **kwargs)
            if response["status"] != "200":
                raise TwitterAPIError(body)
            return body

        try:
            oauth_token = cherrypy.request.params.get("oauth_token")
            oauth_verifier = cherrypy.request.params.get("oauth_verifier")
            oauth_secret_session_key = "twitter_auth.%s.oauth_secret" % self.id

            if not oauth_token or not oauth_verifier:
                # Obtain a request token
                client = Client(consumer)

                location = Location.get_current(relative = False)
                location.query_string["item_action"] = self.id
                callback = quote_plus(str(location))

                body = request(
                    client,
                    "https://api.twitter.com/oauth/request_token"
                    "?oauth_callback=" + callback,
                    "GET"
                )
                data = dict(parse_qsl(body))
                session[oauth_secret_session_key] = data["oauth_token_secret"]

                # Redirect the user to the login form
                auth_url = (
                    "https://api.twitter.com/oauth/authorize?"
                    "oauth_token=%s"
                    "&oauth_callback=%s"
                    % (data["oauth_token"], callback)
                )
                raise cherrypy.HTTPRedirect(auth_url)
            else:
                token = Token(oauth_token, session[oauth_secret_session_key])
                token.set_verifier(oauth_verifier)
                client = Client(consumer, token)
                body = request(
                    client,
                    'https://api.twitter.com/oauth/access_token',
                    "POST"
                )
                data = dict(parse_qsl(body))
                target.auth_token = data["oauth_token"]
                target.auth_secret = data["oauth_token_secret"]
                datastore.commit()

        except TwitterAPIError, ex:
            Notification(
                translations(ex),
                category = "error",
                transient = False
            ).emit()
        else:
            Notification(
                translations(
                    "woost.extensions.twitterpublication."
                    "successful_authorization_notice"
                ),
                category = "success"
            ).emit()

TwitterAuthUserAction("twitter_auth").register()

