import logging
from collections import Counter
from django.core.management.base import BaseCommand
from django.db.models import Q

from TWLight.applications.models import Application
from TWLight.resources.models import Partner
from TWLight.applications.signals import Reminder
from TWLight.users.models import Editor

logger = logging.getLogger(__name__)


class Command(BaseCommand):
    def handle(self, *args, **options):
        # This is not DRY. Originally, this pulled the queryset from
        # TWLight.applications.views.ListApplicationsView.get_queryset().
        # But that now expects a request object. So, we did a copy/paste.
        # We're actually getting apps with a status of PENDING or QUESTION
        # or APPROVED, and their corresponding user preferences being True
        # for partners with a status of AVAILABLE.
        all_apps = (
            Application.objects.filter(
                Q(
                    partner__coordinator__editor__user__userprofile__pending_app_reminders=True
                )
                & Q(status=Application.PENDING)
                | Q(
                    partner__coordinator__editor__user__userprofile__discussion_app_reminders=True
                )
                & Q(status=Application.QUESTION)
                | Q(
                    partner__coordinator__editor__user__userprofile__approved_app_reminders=True
                )
                & Q(status=Application.APPROVED),
                partner__status__in=[Partner.AVAILABLE],
                editor__isnull=False,
            )
            .exclude(editor__user__groups__name="restricted")
            .order_by("status", "partner", "date_created")
        )
        # A deduplicated dict of coordinators from the pending app queryset, along
        # with a count of how many total pending apps they have
        coordinators = Counter(
            all_apps.values_list(
                "partner__coordinator__editor",
                "partner__coordinator__email",
                "partner__coordinator__editor__user__userprofile__lang",
            )
        )

        for coordinator, count in list(coordinators.items()):
            try:
                # We create a dictionary with the three status codes
                # we'd want to send emails for, and their corresponding
                # counts.
                app_status_and_count = {
                    Application.PENDING: all_apps.filter(
                        status=Application.PENDING,
                        partner__coordinator__editor=coordinator[0],
                    ).count(),
                    Application.QUESTION: all_apps.filter(
                        status=Application.QUESTION,
                        partner__coordinator__editor=coordinator[0],
                    ).count(),
                    Application.APPROVED: all_apps.filter(
                        status=Application.APPROVED,
                        partner__coordinator__editor=coordinator[0],
                    ).count(),
                }
                editor = Editor.objects.get(id=coordinator[0])
            except Editor.DoesNotExist:
                logger.info(
                    "Editor {} does not exist; skipping.".format(coordinator[0])
                )
                break
            # Only bother with the signal if we have a coordinator email.
            if coordinator[1]:
                Reminder.coordinator_reminder.send(
                    sender=self.__class__,
                    app_status_and_count=app_status_and_count,
                    coordinator_wp_username=editor.wp_username,
                    coordinator_email=coordinator[1],
                    coordinator_lang=coordinator[2],
                )

[((328, 355), 'logging.getLogger', 'logging.getLogger', (['__name__'], {}), '(__name__)\n', (345, 355), False, 'import logging\n'), ((3069, 3106), 'TWLight.users.models.Editor.objects.get', 'Editor.objects.get', ([], {'id': 'coordinator[0]'}), '(id=coordinator[0])\n', (3087, 3106), False, 'from TWLight.users.models import Editor\n'), ((3418, 3643), 'TWLight.applications.signals.Reminder.coordinator_reminder.send', 'Reminder.coordinator_reminder.send', ([], {'sender': 'self.__class__', 'app_status_and_count': 'app_status_and_count', 'coordinator_wp_username': 'editor.wp_username', 'coordinator_email': 'coordinator[1]', 'coordinator_lang': 'coordinator[2]'}), '(sender=self.__class__,\n    app_status_and_count=app_status_and_count, coordinator_wp_username=\n    editor.wp_username, coordinator_email=coordinator[1], coordinator_lang=\n    coordinator[2])\n', (3452, 3643), False, 'from TWLight.applications.signals import Reminder\n'), ((1291, 1370), 'django.db.models.Q', 'Q', ([], {'partner__coordinator__editor__user__userprofile__approved_app_reminders': '(True)'}), '(partner__coordinator__editor__user__userprofile__approved_app_reminders=True)\n', (1292, 1370), False, 'from django.db.models import Q\n'), ((1427, 1457), 'django.db.models.Q', 'Q', ([], {'status': 'Application.APPROVED'}), '(status=Application.APPROVED)\n', (1428, 1457), False, 'from django.db.models import Q\n'), ((921, 999), 'django.db.models.Q', 'Q', ([], {'partner__coordinator__editor__user__userprofile__pending_app_reminders': '(True)'}), '(partner__coordinator__editor__user__userprofile__pending_app_reminders=True)\n', (922, 999), False, 'from django.db.models import Q\n'), ((1056, 1085), 'django.db.models.Q', 'Q', ([], {'status': 'Application.PENDING'}), '(status=Application.PENDING)\n', (1057, 1085), False, 'from django.db.models import Q\n'), ((1104, 1190), 'django.db.models.Q', 'Q', ([], {'partner__coordinator__editor__user__userprofile__discussion_app_reminders': '(True)'}), '(partner__coordinator__editor__user__userprofile__discussion_app_reminders\n    =True)\n', (1105, 1190), False, 'from django.db.models import Q\n'), ((1242, 1272), 'django.db.models.Q', 'Q', ([], {'status': 'Application.QUESTION'}), '(status=Application.QUESTION)\n', (1243, 1272), False, 'from django.db.models import Q\n')]