from datetime import timedelta

from django.test import TestCase
from django.utils import timezone

from freezegun import freeze_time

from newsreader.accounts.tests.factories import UserFactory
from newsreader.news.collection.choices import RuleTypeChoices
from newsreader.news.collection.reddit import RedditScheduler
from newsreader.news.collection.tests.factories import CollectionRuleFactory


@freeze_time("2019-10-30 12:30:00")
class RedditSchedulerTestCase(TestCase):
    def test_simple(self):
        user_1 = UserFactory(
            reddit_access_token="1231414", reddit_refresh_token="5235262"
        )
        user_2 = UserFactory(
            reddit_access_token="3414777", reddit_refresh_token="3423425"
        )

        user_1_rules = [
            CollectionRuleFactory(
                user=user_1,
                type=RuleTypeChoices.subreddit,
                last_run=timezone.now() - timedelta(days=4),
                enabled=True,
            ),
            CollectionRuleFactory(
                user=user_1,
                type=RuleTypeChoices.subreddit,
                last_run=timezone.now() - timedelta(days=3),
                enabled=True,
            ),
            CollectionRuleFactory(
                user=user_1,
                type=RuleTypeChoices.subreddit,
                last_run=timezone.now() - timedelta(days=2),
                enabled=True,
            ),
        ]

        user_2_rules = [
            CollectionRuleFactory(
                user=user_2,
                type=RuleTypeChoices.subreddit,
                last_run=timezone.now() - timedelta(days=4),
                enabled=True,
            ),
            CollectionRuleFactory(
                user=user_2,
                type=RuleTypeChoices.subreddit,
                last_run=timezone.now() - timedelta(days=3),
                enabled=True,
            ),
            CollectionRuleFactory(
                user=user_2,
                type=RuleTypeChoices.subreddit,
                last_run=timezone.now() - timedelta(days=2),
                enabled=True,
            ),
        ]

        scheduler = RedditScheduler()
        scheduled_subreddits = scheduler.get_scheduled_rules()

        user_1_batch = [subreddit.pk for subreddit in scheduled_subreddits[0]]

        self.assertIn(user_1_rules[0].pk, user_1_batch)
        self.assertIn(user_1_rules[1].pk, user_1_batch)
        self.assertIn(user_1_rules[2].pk, user_1_batch)

        user_2_batch = [subreddit.pk for subreddit in scheduled_subreddits[1]]

        self.assertIn(user_2_rules[0].pk, user_2_batch)
        self.assertIn(user_2_rules[1].pk, user_2_batch)
        self.assertIn(user_2_rules[2].pk, user_2_batch)

    def test_max_amount(self):
        users = UserFactory.create_batch(
            reddit_access_token="1231414", reddit_refresh_token="5235262", size=5
        )

        nested_rules = [
            CollectionRuleFactory.create_batch(
                name=f"rule-{index}",
                type=RuleTypeChoices.subreddit,
                last_run=timezone.now() - timedelta(seconds=index),
                enabled=True,
                user=user,
                size=15,
            )
            for index, user in enumerate(users)
        ]

        rules = [rule for rule_list in nested_rules for rule in rule_list]

        scheduler = RedditScheduler()
        scheduled_subreddits = [
            subreddit.pk
            for batch in scheduler.get_scheduled_rules()
            for subreddit in batch
        ]

        for rule in rules[16:76]:
            with self.subTest(rule=rule):
                self.assertIn(rule.pk, scheduled_subreddits)

        for rule in rules[0:15]:
            with self.subTest(rule=rule):
                self.assertNotIn(rule.pk, scheduled_subreddits)

    def test_max_user_amount(self):
        user = UserFactory(
            reddit_access_token="1231414", reddit_refresh_token="5235262"
        )

        rules = [
            CollectionRuleFactory(
                name=f"rule-{index}",
                type=RuleTypeChoices.subreddit,
                last_run=timezone.now() - timedelta(seconds=index),
                enabled=True,
                user=user,
            )
            for index in range(1, 17)
        ]

        scheduler = RedditScheduler()
        scheduled_subreddits = [
            subreddit.pk
            for batch in scheduler.get_scheduled_rules()
            for subreddit in batch
        ]

        for rule in rules[1:16]:
            with self.subTest(rule=rule):
                self.assertIn(rule.pk, scheduled_subreddits)

        self.assertNotIn(rules[0].pk, scheduled_subreddits)
