from os import mkdir
from os.path import exists

import numpy as np
import pandas as pd

from old.project import CassandraUtils
from old.project import get_time

RTD_STS_KEY = 'retweetedStatus'
MT_STS_KEY = 'userMentionEntities'
PATH = '/home/joao/Dev/Data/Twitter/'
FRIENDS_PATH = '/home/joao/Dev/Data/Twitter/friendships/'


def form_tweet(tweet, date=None):
    return {'id': tweet['id'],
            'lang': tweet['lang'] if 'lang' in tweet else None,
            'text': tweet['text'],
            'date': date or tweet['createdAt'],
            'user': {'id': tweet['user']['id']}}


def folding(tweets):
    last_index = np.ceil(len(tweets) * 0.75).astype(int)
    if last_index < 10:
        return np.array(tweets)
    np_array = np.array(tweets)
    return np_array[0:last_index]


def append_frame(df, df_plus):
    return df.append(df_plus)


def save_frames(file_name, _data):
    if len(_data) > 0:
        data_frame = mount_frame(data=_data)
        df = pd.DataFrame()

        df = append_frame(df, data_frame)
        try:
            df.to_csv(file_name, sep=',', encoding='utf-8')
        except IOError:
            df.to_csv('Saida/retweets/' + file_name.split('/')[len(file_name.split('/')) - 1])


def mount_frame(data):
    data = np.array(data)
    data_frame = pd.DataFrame()
    if np.size(data) > 0:
        data_frame['alter'] = data[:, 1]
        data_frame['tweet'] = data[:, 0]
    return data_frame


class FriendsDataToDataFrame:
    # frame_path = '/home/joao/Dev/Data/Twitter/friends.data/data.frame/'

    def __init__(self):
        self.cass = CassandraUtils()
        self.frame_path = '/home/joao/Dev/Shared/Saida/'
        self.likes_path = self.frame_path + 'likes/'
        self.mentions_path = self.frame_path + 'mentions/'
        self.retweets_path = self.frame_path + 'retweets/'
        print self.retweets_path
        try:
            if not exists(self.frame_path):
                mkdir(self.frame_path)
            if not exists(self.likes_path):
                mkdir(self.likes_path)
            if not exists(self.mentions_path):
                mkdir(self.mentions_path)
            if not exists(self.retweets_path):
                mkdir(self.retweets_path)
        except Exception as e:
            raise e

    def get_seeds(self):
        # seeds = pd.DataFrame()
        seeds = self.cass.find_seeds();
        # print seeds
        seeds = map(lambda x: x.user_id, seeds)
        return seeds

    #
    # def check_friends_data(self, user_id):
    #     friends = self(user_id=user_id)
    #     data = filter(lambda friend_id: not exists(path=self.frame_path + str(friend_id) + '.csv'), friends['id'])
    #     return len(data) == 0

    # def check_json_interactions(self, seeds=None):
    #     print 'Starting...', get_time(True)
    #     # seeds = load_seeds() if seeds is None else seeds
    #     seeds = self.get_seeds()
    #     for user_id in seeds:
    #         if not self.check_friends_data(user_id=user_id):
    #             return user_id
    #         print user_id
    #     print 'Stopping...', get_time(True)
    #     return None

    def json_interactions(self, _type=None, _force=False, _clean=False, check=False, init_id=0, unique=False):
        print 'Starting...', get_time(True)
        if not unique:
            seeds = self.get_seeds()
            # if _clean:
            #     clean_data(self.frame_path)
            # elif check:
            #     user_id = self.check_json_interactions(seeds=seeds)
            #     if user_id is not None:
            #         self.friends_data(user_id=user_id, _type=_type, force=True)
            #     return Nonea

            seeds = filter(lambda s: s > init_id, seeds)

            for user_id in seeds:
                self.friends_data(user_id=user_id, _type=_type, force=_force)
        else:
            self.friends_data(user_id=init_id, _type=_type, force=_force)

        print 'Stopping...', get_time(True)

    def friends_data(self, user_id, _type, force=False):
        friends = map(lambda x: x.friend_id, self.cass.find_friends(user_id=user_id))
        for friend_id in friends:
            if _type is None:
                pass
            elif _type == 1:
                path = self.likes_path + str(friend_id) + '.csv'
                if not exists(path=path) or force:
                    self.save_likes(friend_id=friend_id)
            elif _type == 2:
                path = self.mentions_path + str(friend_id) + '.csv'
                if not exists(path=path) or force:
                    self.save_mentions(friend_id=friend_id)
            elif _type == 3:
                path = self.retweets_path + str(friend_id) + '.csv'
                if not exists(path=path) or force:
                    self.save_retweets(friend_id=friend_id)
            else:
                pass

            print user_id, friend_id, get_time()

    def save_likes(self, friend_id):
        likes = self.cass.find_likes(user_id=friend_id)
        likes_data = map(lambda tt: [tt['id'], tt['user']['id']], likes)
        save_frames(self.likes_path + str(friend_id) + '.csv', likes_data)

    def save_retweets(self, friend_id, _tweets=None):
        tweets = _tweets or self.cass.find_tweets(user_id=friend_id)
        retweets = self.cass.find_retweets(tweets=tweets)
        retweets_data = map(lambda tt: [tt[RTD_STS_KEY]['id'], tt[RTD_STS_KEY]['user']['id']], retweets)
        save_frames(self.retweets_path + str(friend_id) + '.csv', retweets_data)

    def save_mentions(self, friend_id, _tweets=None):
        tweets = _tweets or self.cass.find_tweets(user_id=friend_id)
        mentions = self.cass.find_mentions(tweets=tweets)
        mentions_data = []
        for tweet in mentions:
            mentions_data.extend(map(lambda mention: [tweet['id'], mention['id']], tweet[MT_STS_KEY]))
        save_frames(self.mentions_path + str(friend_id) + '.csv', mentions_data)
