from selenium.webdriver.chrome.options import Options
from selenium import webdriver

import logging
import coloredlogs
import os
import pathlib
import time

import twitter as tt
from utils import retry
from fetch_likes import get_user_likes, login
from conf.settings import USER_ID, USERNAME, PASSWORD

CURR_PATH = pathlib.Path(__file__).parent.absolute()
TWEETS_FOLDER = os.path.join(CURR_PATH, 'screenshots')
LIKED_FOLDER = os.path.join(CURR_PATH, 'screenshots', 'liked')


class TwitterListener():
    def __init__(self, user_id=USER_ID, search_base=40):
        # Configure log
        coloredlogs.install()
        logging.basicConfig()
        self.logger = logging.getLogger('TwitterListener')
        self.logger.setLevel(logging.DEBUG)

        # Set chrome options
        chrome_options = Options()
        chrome_options.add_argument('--headless')
        chrome_options.add_argument("--no-sandbox")
        self.driver = webdriver.Chrome(options=chrome_options)
        # Create formatter, file handler and add they to the handlers
        formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        fh = logging.FileHandler('twitter.log')
        fh.setFormatter(formatter)
        self.logger.addHandler(fh)

        self.search_base = search_base
        self.user_id = user_id
        self.target = tt.get_username_from_id(user_id)

        self.is_logged = False,
        self.has_previous_tweets = False
        self.has_previous_friends = False
        self.has_previous_likes = False

    def _get_new_tweets(self):
        if(not self.has_previous_tweets):
            self.previous_tweets_ids = tt.get_ids_from_tweets(
                tt.get_tweets(user_id=self.user_id, count=self.search_base))
            self.has_previous_tweets = True

        last_tweets = tt.get_tweets(user_id=self.user_id,
                                    count=self.search_base)
        last_tweets_ids = tt.get_ids_from_tweets(last_tweets)

        diff_tweets = self._get_new_diff(
            last_tweets_ids, self.previous_tweets_ids)

        if diff_tweets:
            new_tweets = [last_tweets[i] for i in range(len(diff_tweets))]
            self.previous_tweets_ids = last_tweets_ids
            new_tweets.reverse()
            return new_tweets
        return []

    def _get_new_likes(self):
        count = self.search_base/2

        if(not self.is_logged):
            login(self.driver, USERNAME, PASSWORD)
            self.is_logged = True
        if(not self.has_previous_likes):
            self.previous_likes_ids = get_user_likes(
                self.driver, self.target, count=count)
            self.has_previous_likes = True

        new_likes_ids = get_user_likes(
            self.driver, self.target, count=count)
        diff_tweets = self._get_new_diff(
            new_likes_ids, self.previous_likes_ids)

        if diff_tweets:
            self.previous_likes_ids = new_likes_ids
            diff_tweets.reverse()
            return diff_tweets

        return []

    def _get_new_diff(self, curr, old):
        count = len(old)
        return list(set(curr[:count//2]) -
                    set(old))

    def _get_abs_diff(self, first_list, second_list):
        return list(set(first_list) - set(second_list))

    def print_new_tweets(self):
        try:
            new_tweets = self._get_new_tweets()
            for tweet in new_tweets:
                tweet_id = str(tweet['id'])
                tweet_url = tt.get_url(tweet)

                # Get image
                self.logger.info('New tweet %s', tweet_url)
                img_path = os.path.join(TWEETS_FOLDER, f'{tweet_id}.png')
                retry(tt.print_tweet, tweet_url,
                      self.driver, output_path=img_path)
                self.logger.debug('Take a screenshot of tweet')

                # Tweet image

                tweet_msg = 'Jair Bolsonaro acabou de twittar'
                self.logger.debug(
                    f'Is a retweet: {"retweeted_status" in tweet}')
                if('retweeted_status' in tweet):
                    tweet_msg = 'Jair Bolsonaro acabou de retweetar'

                tt.tweet_print(img_path, tweet_url, tweet_msg)
                self.logger.debug('Tweet the screenshot')
        except Exception as e:
            self.logger.error(e)

    def print_new_likes(self):
        try:
            new_likes = self._get_new_likes()
            for t_id in new_likes:
                t_url = f'https://twitter.com/{self.target}/status/{t_id}'

                # Get image
                self.logger.info('New like %s', t_url)
                img_path = os.path.join(LIKED_FOLDER, f'{t_id}.png')
                retry(tt.print_tweet, t_url, self.driver, output_path=img_path)
                self.logger.debug('Take a screenshot of tweet')

                # Tweet image
                t_msg = 'Jair Bolsonaro acabou de curtir esse tweet'
                tt.tweet_print(img_path, t_url, t_msg)
                self.logger.debug('Tweet the screenshot')
        except Exception as e:
            self.logger.error(e)

    def watch_friends(self):
        try:
            if(not self.has_previous_friends):
                self.previous_friends = tt.get_friends_ids(
                    user_id=self.user_id)
                self.has_previous_friends = True

            last_friends = tt.get_friends_ids()

            new_friends = self._get_abs_diff(
                last_friends, self.previous_friends)
            unfriends = self._get_abs_diff(self.previous_friends, last_friends)

            for user_id in new_friends:
                username = tt.get_username_from_id(user_id=user_id)
                self.logger.info(f'New friend: @{username}')
                retry(
                    tt.update_status,
                    status=(
                        f'Jair Bolsonaro aparentemente está seguindo @{username}.'
                        '\n(Esse bot não consegue verificar se essa atualização foi gerada '
                        'por um follow ou por uma reativação de conta)'
                    )
                )

            for user_id in unfriends:
                username = tt.get_username_from_id(user_id=user_id)
                self.logger.info(f'Unfriend: @{username}')
                retry(
                    tt.update_status,
                    status=(
                        f'Jair Bolsonaro aparentemente deixou de seguir @{username}.'
                        '\n(Esse bot não consegue verificar se essa atualização foi gerada '
                        'por um unfollow, suspensão ou block.)'
                    )
                )

            self.previous_friends = last_friends
        except Exception as e:
            self.logger.error(e)

[(16, 'os.path.join', 'os.path.join', False, 'import os\n'), (17, 'os.path.join', 'os.path.join', False, 'import os\n'), (23, 'coloredlogs.install', 'coloredlogs.install', False, 'import coloredlogs\n'), (24, 'logging.basicConfig', 'logging.basicConfig', False, 'import logging\n'), (25, 'logging.getLogger', 'logging.getLogger', False, 'import logging\n'), (29, 'selenium.webdriver.chrome.options.Options', 'Options', False, 'from selenium.webdriver.chrome.options import Options\n'), (32, 'selenium.webdriver.Chrome', 'webdriver.Chrome', False, 'from selenium import webdriver\n'), (34, 'logging.Formatter', 'logging.Formatter', False, 'import logging\n'), (36, 'logging.FileHandler', 'logging.FileHandler', False, 'import logging\n'), (42, 'twitter.get_username_from_id', 'tt.get_username_from_id', True, 'import twitter as tt\n'), (55, 'twitter.get_tweets', 'tt.get_tweets', True, 'import twitter as tt\n'), (57, 'twitter.get_ids_from_tweets', 'tt.get_ids_from_tweets', True, 'import twitter as tt\n'), (80, 'fetch_likes.get_user_likes', 'get_user_likes', False, 'from fetch_likes import get_user_likes, login\n'), (15, 'pathlib.Path', 'pathlib.Path', False, 'import pathlib\n'), (73, 'fetch_likes.login', 'login', False, 'from fetch_likes import get_user_likes, login\n'), (76, 'fetch_likes.get_user_likes', 'get_user_likes', False, 'from fetch_likes import get_user_likes, login\n'), (153, 'twitter.get_friends_ids', 'tt.get_friends_ids', True, 'import twitter as tt\n'), (52, 'twitter.get_tweets', 'tt.get_tweets', True, 'import twitter as tt\n'), (105, 'twitter.get_url', 'tt.get_url', True, 'import twitter as tt\n'), (109, 'os.path.join', 'os.path.join', False, 'import os\n'), (110, 'utils.retry', 'retry', False, 'from utils import retry\n'), (122, 'twitter.tweet_print', 'tt.tweet_print', True, 'import twitter as tt\n'), (135, 'os.path.join', 'os.path.join', False, 'import os\n'), (136, 'utils.retry', 'retry', False, 'from utils import retry\n'), (141, 'twitter.tweet_print', 'tt.tweet_print', True, 'import twitter as tt\n'), (149, 'twitter.get_friends_ids', 'tt.get_friends_ids', True, 'import twitter as tt\n'), (160, 'twitter.get_username_from_id', 'tt.get_username_from_id', True, 'import twitter as tt\n'), (162, 'utils.retry', 'retry', False, 'from utils import retry\n'), (172, 'twitter.get_username_from_id', 'tt.get_username_from_id', True, 'import twitter as tt\n'), (174, 'utils.retry', 'retry', False, 'from utils import retry\n')]