from requests_oauthlib import OAuth1Session
from json import JSONDecoder
from staccato import utils


def _define_endpoint(method, endpoint, id=False):
    if id:
        def fn(self, id, **kwargs):
            url = "{}/{}.json".format(endpoint, id)
            return self.request(method, url, params=kwargs)
        return fn
    else:
        def fn(self, **kwargs):
            url = "{}.json".format(endpoint)
            return self.request(method, url, params=kwargs)
        return fn

class Twitter():
    API = "https://api.twitter.com/1.1/"

    def __init__(self, session=None):
        self.session = session

    def auth(self, consumer_key, consumer_secret, access_token_key, access_token_secret):

        session = OAuth1Session(
            consumer_key,
            client_secret=consumer_secret,
            resource_owner_key=access_token_key,
            resource_owner_secret=access_token_secret)

        self.session=session

    def request(self, method='get', endpoint='', **kwargs):

        def _parsed(s):
            try:
                return JSONDecoder().decode(s)
            except:
                return s

        if self.session is None:
            raise TwitterAuthException()

        _url=Twitter.API + endpoint
        parsed=_parsed(self.session.request(method, _url, **kwargs).text)

        return parsed


    def lookup(self, user_ids):
        result=[]
        for ids in utils.chunk(user_ids, 100):
            r=self.request("get", "users/lookup.json", params={"user_id": ','.join(ids)})
            result.extend(r)
        return result

    def remove_user(self, user_id):
        return self.request("post", "friendships/destroy.json", params={"user_id": user_id})

    get_followers    = _define_endpoint("get", "followers/ids")
    get_followings   = _define_endpoint("get", "friends/ids")
    
    statuses_mentions_timeline              = _define_endpoint("get","statuses/mentions_timeline")
    statuses_user_timeline                  = _define_endpoint("get","statuses/user_timeline")
    statuses_home_timeline                  = _define_endpoint("get","statuses/home_timeline")
    statuses_retweets_of_me                 = _define_endpoint("get","statuses/retweets_of_me")
    statuses_retweets                       = _define_endpoint("get","statuses/retweets", True)
    statuses_show                           = _define_endpoint("get","statuses/show", True)
    statuses_destroy                        = _define_endpoint("post","statuses/destroy", True)
    statuses_update                         = _define_endpoint("post","statuses/update")
    statuses_retweet                        = _define_endpoint("post","statuses/retweet")
    statuses_update_with_media              = _define_endpoint("post","statuses/update_with_media")
    statuses_oembed                         = _define_endpoint("get","statuses/oembed")
    statuses_retweeters_ids                 = _define_endpoint("get","statuses/retweeters/ids")
    statuses_lookup                         = _define_endpoint("get","statuses/lookup")
    media_upload                            = _define_endpoint("post","media/upload")
    direct_messages_sent                    = _define_endpoint("get","direct_messages/sent")
    direct_messages_show                    = _define_endpoint("get","direct_messages/show")
    search_tweets                           = _define_endpoint("get","search/tweets")
    direct_messages                         = _define_endpoint("get","direct_messages")
    direct_messages_destroy                 = _define_endpoint("post","direct_messages/destroy")
    direct_messages_new                     = _define_endpoint("post","direct_messages/new")
    friendships_no_retweets_ids             = _define_endpoint("get","friendships/no_retweets/ids")
    friends_ids                             = _define_endpoint("get","friends/ids")
    followers_ids                           = _define_endpoint("get","followers/ids")
    friendships_incoming                    = _define_endpoint("get","friendships/incoming")
    friendships_outgoing                    = _define_endpoint("get","friendships/outgoing")
    friendships_create                      = _define_endpoint("post","friendships/create")
    friendships_destroy                     = _define_endpoint("post","friendships/destroy")
    friendships_update                      = _define_endpoint("post","friendships/update")
    friendships_show                        = _define_endpoint("get","friendships/show")
    friends_list                            = _define_endpoint("get","friends/list")
    followers_list                          = _define_endpoint("get","followers/list")
    friendships_lookup                      = _define_endpoint("get","friendships/lookup")
    account_settings                        = _define_endpoint("get","account/settings")
    account_verify_credentials              = _define_endpoint("get","account/verify_credentials")
    account_settings                        = _define_endpoint("post","account/settings")
    account_update_delivery_device          = _define_endpoint("post","account/update_delivery_device")
    account_update_profile                  = _define_endpoint("post","account/update_profile")
    account_update_profile_background_image = _define_endpoint("post","account/update_profile_background_image")
    account_update_profile_image            = _define_endpoint("post","account/update_profile_image")
    blocks_list                             = _define_endpoint("get","blocks/list")
    blocks_ids                              = _define_endpoint("get","blocks/ids")
    blocks_create                           = _define_endpoint("post","blocks/create")
    blocks_destroy                          = _define_endpoint("post","blocks/destroy")
    users_lookup                            = _define_endpoint("get","users/lookup")
    users_show                              = _define_endpoint("get","users/show")
    users_search                            = _define_endpoint("get","users/search")
    account_remove_profile_banner           = _define_endpoint("post","account/remove_profile_banner")
    account_update_profile_banner           = _define_endpoint("post","account/update_profile_banner")
    users_profile_banner                    = _define_endpoint("get","users/profile_banner")
    favorites_list                          = _define_endpoint("get","favorites/list")
    favorites_destroy                       = _define_endpoint("post","favorites/destroy")
    favorites_create                        = _define_endpoint("post","favorites/create")
    lists_list                              = _define_endpoint("get","lists/list")
    lists_statuses                          = _define_endpoint("get","lists/statuses")
    lists_members_destroy                   = _define_endpoint("post","lists/members/destroy")
    lists_memberships                       = _define_endpoint("get","lists/memberships")
    lists_subscribers                       = _define_endpoint("get","lists/subscribers")
    lists_subscribers_create                = _define_endpoint("post","lists/subscribers/create")
    lists_subscribers_show                  = _define_endpoint("get","lists/subscribers/show")
    lists_subscribers_destroy               = _define_endpoint("post","lists/subscribers/destroy")
    lists_members_create_all                = _define_endpoint("post","lists/members/create_all")
    lists_members_show                      = _define_endpoint("get","lists/members/show")
    lists_members                           = _define_endpoint("get","lists/members")
    lists_members_create                    = _define_endpoint("post","lists/members/create")
    lists_destroy                           = _define_endpoint("post","lists/destroy")
    lists_update                            = _define_endpoint("post","lists/update")
    lists_create                            = _define_endpoint("post","lists/create")
    lists_show                              = _define_endpoint("get","lists/show")
    lists_subscriptions                     = _define_endpoint("get","lists/subscriptions")
    lists_members_destroy_all               = _define_endpoint("post","lists/members/destroy_all")
    lists_ownerships                        = _define_endpoint("get","lists/ownerships")
    saved_searches_list                     = _define_endpoint("get","saved_searches/list")
    saved_searches_show                     = _define_endpoint("get","saved_searches/show", True)
    saved_searches_create                   = _define_endpoint("post","saved_searches/create")
    saved_searches_destroy                  = _define_endpoint("post","saved_searches/destroy", True)
    trends_place                            = _define_endpoint("get","trends/place")
    trends_available                        = _define_endpoint("get","trends/available")
    application_rate_limit_status           = _define_endpoint("get","application/rate_limit_status")
    help_configuration                      = _define_endpoint("get","help/configuration")
    help_languages                          = _define_endpoint("get","help/languages")
    help_privacy                            = _define_endpoint("get","help/privacy")
    help_tos                                = _define_endpoint("get","help/tos")
    trends_closest                          = _define_endpoint("get","trends/closest")
    users_report_spam                       = _define_endpoint("post","users/report_spam")
class TwitterAuthException(Exception):
    pass
