import json
from os import path

from tweepy import OAuthHandler, Stream
from tweepy.streaming import StreamListener

from sqlalchemy.orm.exc import NoResultFound

from database import session, Tweet, Hashtag, User

consumer_key = "0qFf4T2xPWVIycLmAwk3rDQ55"
consumer_secret = "LcHpujASn4fIIrQ8sikbCTQ3oyU6T6opchFVWBBqwICahzSE64"
access_token = "4271002872-XLo7TNnE3qvYevqLmT1RBuiJ5CJ3o0DCr3WReAT"
acces_token_secret = "ulZ3dA25zuC6BGJgaFowCSTIm6gKVtOa4x9y7tO0IUDIx"

auth = OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, acces_token_secret)

def save_tweets():
    directory = _get_dir_absolute_path()
    filepath = path.join(directory, "tweets.json")
    
    listener = DatabaseListener(number_tweets_to_save = 1000, filepath=filepath)
    
    stream = Stream(auth, listener)
    languages = ("en",)
    try:
        stream.sample(languages = languages)
    except KeyboardInterrupt:
        listener.file.close()


class DatabaseListener(StreamListener):
    def __init__(self, number_tweets_to_save, filepath = None):
        self._final_count = number_tweets_to_save
        self._current_count = 0
        if filepath is None:
            filepath = "tweets.txt"
        self.file = open(filepath,"w")

#Slightly dangerous due to circular references>>
    def __del__(self):
        self.file.close()

    def on_data(self, raw_data):
        data = json.loads(raw_data)
        json.dump(raw_data, self.file)
        self.file.write("\n")
        if "in_reply_to_status_id" in data:
            return self.on_status(data)

    def on_status(self, data):
        #this method is define in this file
        save_to_database(data)

        self._current_count += 1
        print("status count: {}".format(self._current_count))
        if self._current_count >= self._final_count:
            return False

def create_user_helper(user_data):
    #alias to shorten calls
    u = user_data
    user = user(uid = u["id_str"],
                name = u["name"],
                screen_name = u["screen_name"],
                created_at = u["created_at"],
                description = u.get("description"),
                followers_count = u["followers_count"],
                statuses_count = u["statuses_count"],
                favourites_count = u["favourites_count"],
                listed_count = u["listed_count"],
                geo_enabled = u["geo_enabled"],
                lang = u.get("lang"))
    return user


def create_tweet_helper(tweet_data, user):
    #alias for shorten calls
    t = tweet_data
    retweet = True if t["text"][:3] == "RT " else False
    coordinates = json.dumps(t["coordinates"])
    tweet = Tweet(tid=t["id_str"],
                  tweet=t["text"],
                  user=user,
                  coordinates=coordinates,
                  created_at = t["created_at"],
                  favorite_count = t["favorite_count"],
                  in_reply_to_screen_name = t["in_reply_to_screen_name"],
                  in_reply_to_status_id = t["in_reply_to_status_id"],
                  in_reply_to_user_id = t["in_reply_to_user_id"],
                  lang = t.get("lang"),
                  quoted_status_id = t.get("quoted_status_id"),
                  retweet_count = t["retweet_count"],
                  source = t["source"],
                  is_retweet = retweet)
    
    return tweet

def save_to_database(data):
    try:
        user = session.query(User).filter_by(id=str(data["user"]["id"])).one()
    except NoResultFound:
        user = create_user_helper(data["user"])
        session.add(user)

    hashtag_results = []
    hashtags = data["entities"]["hashtags"]
    for hashtag in hashtags:
        hashtag = hashtag["text"].lower()
        try:
            hashtag_obj=session.query(Hashtag).filer_by(text = hashtag).one()
        except NoResutlFound:
            user = create_
            hashtag_obj = Hashtag(text = hashtag)
            session.add(hashtag_obj)
        
        hashtag_results.append(hashtag_obj)

        tweet = create_tweet_helper(data, user)

        for hashtag in hashtag_results:
            tweet.hashtags.append(hashtag)

        session.add(tweet)
        session.commit()


[((16, 7, 16, 50), 'tweepy.OAuthHandler', 'OAuthHandler', ({(16, 20, 16, 32): 'consumer_key', (16, 34, 16, 49): 'consumer_secret'}, {}), '(consumer_key, consumer_secret)', False, 'from tweepy import OAuthHandler, Stream\n'), ((21, 15, 21, 50), 'os.path.join', 'path.join', ({(21, 25, 21, 34): 'directory', (21, 36, 21, 49): '"""tweets.json"""'}, {}), "(directory, 'tweets.json')", False, 'from os import path\n'), ((25, 13, 25, 35), 'tweepy.Stream', 'Stream', ({(25, 20, 25, 24): 'auth', (25, 26, 25, 34): 'listener'}, {}), '(auth, listener)', False, 'from tweepy import OAuthHandler, Stream\n'), ((82, 18, 82, 46), 'json.dumps', 'json.dumps', ({(82, 29, 82, 45): "t['coordinates']"}, {}), "(t['coordinates'])", False, 'import json\n'), ((46, 15, 46, 35), 'json.loads', 'json.loads', ({(46, 26, 46, 34): 'raw_data'}, {}), '(raw_data)', False, 'import json\n'), ((47, 8, 47, 38), 'json.dump', 'json.dump', ({(47, 18, 47, 26): 'raw_data', (47, 28, 47, 37): 'self.file'}, {}), '(raw_data, self.file)', False, 'import json\n'), ((125, 8, 125, 26), 'database.session.add', 'session.add', ({(125, 20, 125, 25): 'tweet'}, {}), '(tweet)', False, 'from database import session, Tweet, Hashtag, User\n'), ((126, 8, 126, 24), 'database.session.commit', 'session.commit', ({}, {}), '()', False, 'from database import session, Tweet, Hashtag, User\n'), ((105, 8, 105, 25), 'database.session.add', 'session.add', ({(105, 20, 105, 24): 'user'}, {}), '(user)', False, 'from database import session, Tweet, Hashtag, User\n'), ((115, 26, 115, 49), 'database.Hashtag', 'Hashtag', (), '', False, 'from database import session, Tweet, Hashtag, User\n'), ((116, 12, 116, 36), 'database.session.add', 'session.add', ({(116, 24, 116, 35): 'hashtag_obj'}, {}), '(hashtag_obj)', False, 'from database import session, Tweet, Hashtag, User\n'), ((102, 15, 102, 34), 'database.session.query', 'session.query', ({(102, 29, 102, 33): 'User'}, {}), '(User)', False, 'from database import session, Tweet, Hashtag, User\n'), ((112, 24, 112, 46), 'database.session.query', 'session.query', ({(112, 38, 112, 45): 'Hashtag'}, {}), '(Hashtag)', False, 'from database import session, Tweet, Hashtag, User\n')]