from django.core.exceptions import ObjectDoesNotExist

from celery.exceptions import Reject
from celery.utils.log import get_task_logger

from newsreader.accounts.models import User
from newsreader.celery import app
from newsreader.news.collection.choices import RuleTypeChoices
from newsreader.news.collection.feed import FeedCollector
from newsreader.utils.celery import MemCacheLock


logger = get_task_logger(__name__)


class FeedTask(app.Task):
    name = "FeedTask"
    ignore_result = True

    def run(self, user_pk):
        try:
            user = User.objects.get(pk=user_pk)
        except ObjectDoesNotExist:
            message = f"User {user_pk} does not exist"
            logger.exception(message)

            raise Reject(reason=message, requeue=False)

        with MemCacheLock(f"{user.email}-task", self.app.oid) as acquired:
            if acquired:
                logger.info(f"Running task for user {user_pk}")

                rules = user.rules.enabled().filter(type=RuleTypeChoices.feed)

                collector = FeedCollector()
                collector.collect(rules=rules)
            else:
                logger.warning(
                    f"Cancelling task due to existing lock for user {user_pk}"
                )

                raise Reject(reason="Task already running", requeue=False)


class FaviconTask(app.Task):
    name = "FaviconTask"
    ignore_result = True

    def run(self, user_pk):
        from newsreader.news.collection.favicon import FaviconCollector

        try:
            user = User.objects.get(pk=user_pk)
        except ObjectDoesNotExist:
            message = f"User {user_pk} does not exist"
            logger.exception(message)

            raise Reject(reason=message, requeue=False)

        with MemCacheLock("f{user.email}-favicon-task", self.app.oid) as acquired:
            if acquired:
                logger.info(f"Running favicon task for user {user_pk}")

                rules = user.rules.enabled().filter(type=RuleTypeChoices.feed)

                collector = FaviconCollector()
                collector.collect(rules=rules)
            else:
                logger.warning("Cancelling task due to existing lock")

                raise Reject(reason="Task already running", requeue=False)


FeedTask = app.register_task(FeedTask())
FaviconTask = app.register_task(FaviconTask())
