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, 16, 16, 54), 'os.path.join', 'os.path.join', ({(16, 29, 16, 38): 'CURR_PATH', (16, 40, 16, 53): '"""screenshots"""'}, {}), "(CURR_PATH, 'screenshots')", False, 'import os\n'), ((17, 15, 17, 62), 'os.path.join', 'os.path.join', ({(17, 28, 17, 37): 'CURR_PATH', (17, 39, 17, 52): '"""screenshots"""', (17, 54, 17, 61): '"""liked"""'}, {}), "(CURR_PATH, 'screenshots', 'liked')", False, 'import os\n'), ((23, 8, 23, 29), 'coloredlogs.install', 'coloredlogs.install', ({}, {}), '()', False, 'import coloredlogs\n'), ((24, 8, 24, 29), 'logging.basicConfig', 'logging.basicConfig', ({}, {}), '()', False, 'import logging\n'), ((25, 22, 25, 58), 'logging.getLogger', 'logging.getLogger', ({(25, 40, 25, 57): '"""TwitterListener"""'}, {}), "('TwitterListener')", False, 'import logging\n'), ((29, 25, 29, 34), 'selenium.webdriver.chrome.options.Options', 'Options', ({}, {}), '()', False, 'from selenium.webdriver.chrome.options import Options\n'), ((32, 22, 32, 62), 'selenium.webdriver.Chrome', 'webdriver.Chrome', (), '', False, 'from selenium import webdriver\n'), ((34, 20, 35, 67), 'logging.Formatter', 'logging.Formatter', ({(35, 12, 35, 66): '"""%(asctime)s - %(name)s - %(levelname)s - %(message)s"""'}, {}), "('%(asctime)s - %(name)s - %(levelname)s - %(message)s')", False, 'import logging\n'), ((36, 13, 36, 47), 'logging.FileHandler', 'logging.FileHandler', ({(36, 33, 36, 46): '"""twitter.log"""'}, {}), "('twitter.log')", False, 'import logging\n'), ((42, 22, 42, 54), 'twitter.get_username_from_id', 'tt.get_username_from_id', ({(42, 46, 42, 53): 'user_id'}, {}), '(user_id)', True, 'import twitter as tt\n'), ((55, 22, 56, 59), 'twitter.get_tweets', 'tt.get_tweets', (), '', True, 'import twitter as tt\n'), ((57, 26, 57, 61), 'twitter.get_ids_from_tweets', 'tt.get_ids_from_tweets', ({(57, 49, 57, 60): 'last_tweets'}, {}), '(last_tweets)', True, 'import twitter as tt\n'), ((80, 24, 81, 50), 'fetch_likes.get_user_likes', 'get_user_likes', (), '', False, 'from fetch_likes import get_user_likes, login\n'), ((15, 12, 15, 34), 'pathlib.Path', 'pathlib.Path', ({(15, 25, 15, 33): '__file__'}, {}), '(__file__)', False, 'import pathlib\n'), ((73, 12, 73, 50), 'fetch_likes.login', 'login', ({(73, 18, 73, 29): 'self.driver', (73, 31, 73, 39): 'USERNAME', (73, 41, 73, 49): 'PASSWORD'}, {}), '(self.driver, USERNAME, PASSWORD)', False, 'from fetch_likes import get_user_likes, login\n'), ((76, 38, 77, 54), 'fetch_likes.get_user_likes', 'get_user_likes', (), '', False, 'from fetch_likes import get_user_likes, login\n'), ((153, 27, 153, 47), 'twitter.get_friends_ids', 'tt.get_friends_ids', ({}, {}), '()', True, 'import twitter as tt\n'), ((52, 16, 52, 75), 'twitter.get_tweets', 'tt.get_tweets', (), '', True, 'import twitter as tt\n'), ((105, 28, 105, 45), 'twitter.get_url', 'tt.get_url', ({(105, 39, 105, 44): 'tweet'}, {}), '(tweet)', True, 'import twitter as tt\n'), ((109, 27, 109, 73), 'os.path.join', 'os.path.join', ({(109, 40, 109, 53): 'TWEETS_FOLDER', (109, 55, 109, 72): 'f"""{tweet_id}.png"""'}, {}), "(TWEETS_FOLDER, f'{tweet_id}.png')", False, 'import os\n'), ((110, 16, 111, 56), 'utils.retry', 'retry', (), '', False, 'from utils import retry\n'), ((122, 16, 122, 62), 'twitter.tweet_print', 'tt.tweet_print', ({(122, 31, 122, 39): 'img_path', (122, 41, 122, 50): 'tweet_url', (122, 52, 122, 61): 'tweet_msg'}, {}), '(img_path, tweet_url, tweet_msg)', True, 'import twitter as tt\n'), ((135, 27, 135, 68), 'os.path.join', 'os.path.join', ({(135, 40, 135, 52): 'LIKED_FOLDER', (135, 54, 135, 67): 'f"""{t_id}.png"""'}, {}), "(LIKED_FOLDER, f'{t_id}.png')", False, 'import os\n'), ((136, 16, 136, 79), 'utils.retry', 'retry', (), '', False, 'from utils import retry\n'), ((141, 16, 141, 54), 'twitter.tweet_print', 'tt.tweet_print', ({(141, 31, 141, 39): 'img_path', (141, 41, 141, 46): 't_url', (141, 48, 141, 53): 't_msg'}, {}), '(img_path, t_url, t_msg)', True, 'import twitter as tt\n'), ((149, 40, 150, 41), 'twitter.get_friends_ids', 'tt.get_friends_ids', (), '', True, 'import twitter as tt\n'), ((160, 27, 160, 67), 'twitter.get_username_from_id', 'tt.get_username_from_id', (), '', True, 'import twitter as tt\n'), ((162, 16, 169, 17), 'utils.retry', 'retry', (), '', False, 'from utils import retry\n'), ((172, 27, 172, 67), 'twitter.get_username_from_id', 'tt.get_username_from_id', (), '', True, 'import twitter as tt\n'), ((174, 16, 181, 17), 'utils.retry', 'retry', (), '', False, 'from utils import retry\n')]