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)

[((373, 411), 'os.path.join', 'os.path.join', (['CURR_PATH', '"""screenshots"""'], {}), "(CURR_PATH, 'screenshots')\n", (385, 411), False, 'import os\n'), ((427, 474), 'os.path.join', 'os.path.join', (['CURR_PATH', '"""screenshots"""', '"""liked"""'], {}), "(CURR_PATH, 'screenshots', 'liked')\n", (439, 474), False, 'import os\n'), ((591, 612), 'coloredlogs.install', 'coloredlogs.install', ([], {}), '()\n', (610, 612), False, 'import coloredlogs\n'), ((621, 642), 'logging.basicConfig', 'logging.basicConfig', ([], {}), '()\n', (640, 642), False, 'import logging\n'), ((665, 701), 'logging.getLogger', 'logging.getLogger', (['"""TwitterListener"""'], {}), "('TwitterListener')\n", (682, 701), False, 'import logging\n'), ((801, 810), 'selenium.webdriver.chrome.options.Options', 'Options', ([], {}), '()\n', (808, 810), False, 'from selenium.webdriver.chrome.options import Options\n'), ((935, 975), 'selenium.webdriver.Chrome', 'webdriver.Chrome', ([], {'options': 'chrome_options'}), '(options=chrome_options)\n', (951, 975), False, 'from selenium import webdriver\n'), ((1066, 1139), 'logging.Formatter', 'logging.Formatter', (['"""%(asctime)s - %(name)s - %(levelname)s - %(message)s"""'], {}), "('%(asctime)s - %(name)s - %(levelname)s - %(message)s')\n", (1083, 1139), False, 'import logging\n'), ((1166, 1200), 'logging.FileHandler', 'logging.FileHandler', (['"""twitter.log"""'], {}), "('twitter.log')\n", (1185, 1200), False, 'import logging\n'), ((1364, 1396), 'twitter.get_username_from_id', 'tt.get_username_from_id', (['user_id'], {}), '(user_id)\n', (1387, 1396), True, 'import twitter as tt\n'), ((1834, 1893), 'twitter.get_tweets', 'tt.get_tweets', ([], {'user_id': 'self.user_id', 'count': 'self.search_base'}), '(user_id=self.user_id, count=self.search_base)\n', (1847, 1893), True, 'import twitter as tt\n'), ((1956, 1991), 'twitter.get_ids_from_tweets', 'tt.get_ids_from_tweets', (['last_tweets'], {}), '(last_tweets)\n', (1978, 1991), True, 'import twitter as tt\n'), ((2728, 2781), 'fetch_likes.get_user_likes', 'get_user_likes', (['self.driver', 'self.target'], {'count': 'count'}), '(self.driver, self.target, count=count)\n', (2742, 2781), False, 'from fetch_likes import get_user_likes, login\n'), ((316, 338), 'pathlib.Path', 'pathlib.Path', (['__file__'], {}), '(__file__)\n', (328, 338), False, 'import pathlib\n'), ((2437, 2475), 'fetch_likes.login', 'login', (['self.driver', 'USERNAME', 'PASSWORD'], {}), '(self.driver, USERNAME, PASSWORD)\n', (2442, 2475), False, 'from fetch_likes import get_user_likes, login\n'), ((2589, 2642), 'fetch_likes.get_user_likes', 'get_user_likes', (['self.driver', 'self.target'], {'count': 'count'}), '(self.driver, self.target, count=count)\n', (2603, 2642), False, 'from fetch_likes import get_user_likes, login\n'), ((5400, 5420), 'twitter.get_friends_ids', 'tt.get_friends_ids', ([], {}), '()\n', (5418, 5420), True, 'import twitter as tt\n'), ((1706, 1765), 'twitter.get_tweets', 'tt.get_tweets', ([], {'user_id': 'self.user_id', 'count': 'self.search_base'}), '(user_id=self.user_id, count=self.search_base)\n', (1719, 1765), True, 'import twitter as tt\n'), ((3503, 3520), 'twitter.get_url', 'tt.get_url', (['tweet'], {}), '(tweet)\n', (3513, 3520), True, 'import twitter as tt\n'), ((3637, 3683), 'os.path.join', 'os.path.join', (['TWEETS_FOLDER', 'f"""{tweet_id}.png"""'], {}), "(TWEETS_FOLDER, f'{tweet_id}.png')\n", (3649, 3683), False, 'import os\n'), ((3700, 3767), 'utils.retry', 'retry', (['tt.print_tweet', 'tweet_url', 'self.driver'], {'output_path': 'img_path'}), '(tt.print_tweet, tweet_url, self.driver, output_path=img_path)\n', (3705, 3767), False, 'from utils import retry\n'), ((4187, 4233), 'twitter.tweet_print', 'tt.tweet_print', (['img_path', 'tweet_url', 'tweet_msg'], {}), '(img_path, tweet_url, tweet_msg)\n', (4201, 4233), True, 'import twitter as tt\n'), ((4668, 4709), 'os.path.join', 'os.path.join', (['LIKED_FOLDER', 'f"""{t_id}.png"""'], {}), "(LIKED_FOLDER, f'{t_id}.png')\n", (4680, 4709), False, 'import os\n'), ((4726, 4789), 'utils.retry', 'retry', (['tt.print_tweet', 't_url', 'self.driver'], {'output_path': 'img_path'}), '(tt.print_tweet, t_url, self.driver, output_path=img_path)\n', (4731, 4789), False, 'from utils import retry\n'), ((4970, 5008), 'twitter.tweet_print', 'tt.tweet_print', (['img_path', 't_url', 't_msg'], {}), '(img_path, t_url, t_msg)\n', (4984, 5008), True, 'import twitter as tt\n'), ((5261, 5301), 'twitter.get_friends_ids', 'tt.get_friends_ids', ([], {'user_id': 'self.user_id'}), '(user_id=self.user_id)\n', (5279, 5301), True, 'import twitter as tt\n'), ((5669, 5709), 'twitter.get_username_from_id', 'tt.get_username_from_id', ([], {'user_id': 'user_id'}), '(user_id=user_id)\n', (5692, 5709), True, 'import twitter as tt\n'), ((5787, 6001), 'utils.retry', '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)"""'}), '(tt.update_status, status=\n    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)"""\n    )\n', (5792, 6001), False, 'from utils import retry\n'), ((6215, 6255), 'twitter.get_username_from_id', 'tt.get_username_from_id', ([], {'user_id': 'user_id'}), '(user_id=user_id)\n', (6238, 6255), True, 'import twitter as tt\n'), ((6331, 6540), 'utils.retry', '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.)"""'}), '(tt.update_status, status=\n    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.)"""\n    )\n', (6336, 6540), False, 'from utils import retry\n')]