from rauth import OAuth1Service, OAuth2Service
from flask import current_app, url_for, request, redirect, session
import json
import urllib2
from pprint import pprint


class OAuthSignIn(object):
    providers = None

    def __init__(self, provider_name):
        self.provider_name = provider_name
        credentials = current_app.config['OAUTH_CREDENTIALS'][provider_name]
        self.consumer_id = credentials['id']
        self.consumer_secret = credentials['secret']

    def authorize(self):
        pass

    def callback(self):
        pass

    def get_callback_url(self):
        return url_for('oauth_callback', provider=self.provider_name,
                       _external=True)

    @classmethod
    def get_provider(self, provider_name):
        if self.providers is None:
            self.providers = {}
            for provider_class in self.__subclasses__():
                provider = provider_class()
                self.providers[provider.provider_name] = provider
        return self.providers[provider_name]


class FacebookSignIn(OAuthSignIn):
    def __init__(self):
        super(FacebookSignIn, self).__init__('facebook')
        self.service = OAuth2Service(
            name='facebook',
            client_id=self.consumer_id,
            client_secret=self.consumer_secret,
            authorize_url='https://graph.facebook.com/oauth/authorize',
            access_token_url='https://graph.facebook.com/oauth/access_token',
            base_url='https://graph.facebook.com/'
        )
        print "test"
        print pprint (vars(self.service))

    def authorize(self):
        return redirect(self.service.get_authorize_url(
            scope='email, manage_pages',
            response_type='code',
            redirect_uri=self.get_callback_url())
        )
    def callback(self):
        print "Request"
        print request
        # a = urllib2.urlopen("https://graph.facebook.com/v2.8/oauth/access_token?client_id=201049237061460&redirect_uri=http://localhost:5000/callback/facebook&client_secret=b0628ba953c46beba8b8dc9473d7d4c0&code={0}".format(request.args["code"])).read()
        # print "*"*100
        # print a
        if 'code' not in request.args:
            return None, None, None
        oauth_session = self.service.get_auth_session(
            data={'code': request.args['code'],
                  'grant_type': 'authorization_code',
                  'redirect_uri': self.get_callback_url()}, decoder=json.loads
        )

        # a =  request.args['code']
        # b = urllib2.urlopen("https://graph.facebook.com/v2.8oauth/access_token?client_id=201049237061460&redirect_uri=http://localhost:5000/callback/facebook&client_secret=b0628ba953c46beba8b8dc9473d7d4c0&code={a}").read()
        # print b
        # print '*'*100
        # print self.get_callback_url()
        # print a
        # print request.args['code']
        # a = urllib2.urlopen("https://graph.facebook.com/v2.8/oauth/access_token?client_id=201049237061460&redirect_uri=http://localhost:5000/callback/facebook&client_secret=b0628ba953c46beba8b8dc9473d7d4c0&code={0}".format(request.args['code'])).read()
        print "hello"

        pprint (vars(oauth_session))
        print "access"
        print oauth_session.access_token
        me = oauth_session.get('me?fields=id,email').json()
        print me
        try:
            u_id = me['id']
        except KeyError:
            u_id = ""
        return (
            u_id,
            me.get('email').split('@')[0],  # Facebook does not provide
                                           # username, so the email's user
                                            # is used instead
            me.get('email'),
            oauth_session.access_token
        )


class TwitterSignIn(OAuthSignIn):
    def __init__(self):
        super(TwitterSignIn, self).__init__('twitter')
        self.service = OAuth1Service(
            name='twitter',
            consumer_key=self.consumer_id,
            consumer_secret=self.consumer_secret,
            request_token_url='https://api.twitter.com/oauth/request_token',
            authorize_url='https://api.twitter.com/oauth/authorize',
            access_token_url='https://api.twitter.com/oauth/access_token',
            base_url='https://api.twitter.com/1.1/'
        )

    def authorize(self):
        request_token = self.service.get_request_token(
            params={'oauth_callback': self.get_callback_url()}
        )
        session['request_token'] = request_token
        return redirect(self.service.get_authorize_url(request_token[0]))

    def callback(self):
        request_token = session.pop('request_token')
        if 'oauth_verifier' not in request.args:
            return None, None, None
        oauth_session = self.service.get_auth_session(
            request_token[0],
            request_token[1],
            data={'oauth_verifier': request.args['oauth_verifier']}
        )
        me = oauth_session.get('account/verify_credentials.json').json()
        social_id = 'twitter$' + str(me.get('id'))
        username = me.get('screen_name')
        return social_id, username, None   # Twitter does not provide email

from rauth import OAuth1Service, OAuth2Service
from flask import current_app, url_for, request, redirect, session
import json
import urllib2
from pprint import pprint


class OAuthSignIn(object):
    providers = None

    def __init__(self, provider_name):
        self.provider_name = provider_name
        credentials = current_app.config['OAUTH_CREDENTIALS'][provider_name]
        self.consumer_id = credentials['id']
        self.consumer_secret = credentials['secret']

    def authorize(self):
        pass

    def callback(self):
        pass

    def get_callback_url(self):
        return url_for('oauth_callback', provider=self.provider_name,
                       _external=True)

    @classmethod
    def get_provider(self, provider_name):
        if self.providers is None:
            self.providers = {}
            for provider_class in self.__subclasses__():
                provider = provider_class()
                self.providers[provider.provider_name] = provider
        return self.providers[provider_name]


class FacebookSignIn(OAuthSignIn):
    def __init__(self):
        super(FacebookSignIn, self).__init__('facebook')
        self.service = OAuth2Service(
            name='facebook',
            client_id=self.consumer_id,
            client_secret=self.consumer_secret,
            authorize_url='https://graph.facebook.com/oauth/authorize',
            access_token_url='https://graph.facebook.com/oauth/access_token',
            base_url='https://graph.facebook.com/'
        )
        print "test"
        print pprint (vars(self.service))

    def authorize(self):
        return redirect(self.service.get_authorize_url(
            scope='email, manage_pages',
            response_type='code',
            redirect_uri=self.get_callback_url())
        )
    def callback(self):
        print "Request"
        print request
        # a = urllib2.urlopen("https://graph.facebook.com/v2.8/oauth/access_token?client_id=201049237061460&redirect_uri=http://localhost:5000/callback/facebook&client_secret=b0628ba953c46beba8b8dc9473d7d4c0&code={0}".format(request.args["code"])).read()
        # print "*"*100
        # print a
        if 'code' not in request.args:
            return None, None, None
        oauth_session = self.service.get_auth_session(
            data={'code': request.args['code'],
                  'grant_type': 'authorization_code',
                  'redirect_uri': self.get_callback_url()}, decoder=json.loads
        )

        # a =  request.args['code']
        # b = urllib2.urlopen("https://graph.facebook.com/v2.8oauth/access_token?client_id=201049237061460&redirect_uri=http://localhost:5000/callback/facebook&client_secret=b0628ba953c46beba8b8dc9473d7d4c0&code={a}").read()
        # print b
        # print '*'*100
        # print self.get_callback_url()
        # print a
        # print request.args['code']
        # a = urllib2.urlopen("https://graph.facebook.com/v2.8/oauth/access_token?client_id=201049237061460&redirect_uri=http://localhost:5000/callback/facebook&client_secret=b0628ba953c46beba8b8dc9473d7d4c0&code={0}".format(request.args['code'])).read()
        print "hello"

        pprint (vars(oauth_session))
        print "access"
        print oauth_session.access_token
        me = oauth_session.get('me?fields=id,email').json()
        print me
        try:
            u_id = me['id']
        except KeyError:
            u_id = ""
        return (
            u_id,
            me.get('email').split('@')[0],  # Facebook does not provide
                                           # username, so the email's user
                                            # is used instead
            me.get('email'),
            oauth_session.access_token
        )


class TwitterSignIn(OAuthSignIn):
    def __init__(self):
        super(TwitterSignIn, self).__init__('twitter')
        self.service = OAuth1Service(
            name='twitter',
            consumer_key=self.consumer_id,
            consumer_secret=self.consumer_secret,
            request_token_url='https://api.twitter.com/oauth/request_token',
            authorize_url='https://api.twitter.com/oauth/authorize',
            access_token_url='https://api.twitter.com/oauth/access_token',
            base_url='https://api.twitter.com/1.1/'
        )

    def authorize(self):
        request_token = self.service.get_request_token(
            params={'oauth_callback': self.get_callback_url()}
        )
        session['request_token'] = request_token
        return redirect(self.service.get_authorize_url(request_token[0]))

    def callback(self):
        request_token = session.pop('request_token')
        if 'oauth_verifier' not in request.args:
            return None, None, None
        oauth_session = self.service.get_auth_session(
            request_token[0],
            request_token[1],
            data={'oauth_verifier': request.args['oauth_verifier']}
        )
        me = oauth_session.get('account/verify_credentials.json').json()
        social_id = 'twitter$' + str(me.get('id'))
        username = me.get('screen_name')
        return social_id, username, None   # Twitter does not provide email

# a = urllib2.urlopen("https://graph.facebook.com/v2.8/oauth/access_token?client_id=201049237061460&redirect_uri=http://localhost:5000/callback/facebook&client_secret=b0628ba953c46beba8b8dc9473d7d4c0&code={0}".format(request.args["code"])).read() # print "*"*100 # print a # a =  request.args['code'] # b = urllib2.urlopen("https://graph.facebook.com/v2.8oauth/access_token?client_id=201049237061460&redirect_uri=http://localhost:5000/callback/facebook&client_secret=b0628ba953c46beba8b8dc9473d7d4c0&code={a}").read() # print b # print '*'*100 # print self.get_callback_url() # print a # print request.args['code'] # a = urllib2.urlopen("https://graph.facebook.com/v2.8/oauth/access_token?client_id=201049237061460&redirect_uri=http://localhost:5000/callback/facebook&client_secret=b0628ba953c46beba8b8dc9473d7d4c0&code={0}".format(request.args['code'])).read() # Facebook does not provide # username, so the email's user # is used instead # Twitter does not provide email