# vim:spell:spelllang=fr
# -*- encoding: utf-8 -*-

from optparse import make_option
import datetime
import logging

from django.core.management.base import BaseCommand
from django.conf import settings
from django.core.urlresolvers import reverse
from django.db import transaction

from appli_project.appli_socle import models, utils, middleware

class Command(BaseCommand):
    '''
       Envoi des alertes concernant les nouvelles annonces aux étudiants et
       chercheurs intéressés.
    '''
    can_import_django_settings = True
    output_transaction = True
    requires_model_validation = True
    args = ''
    help = 'Envoi des alertes concernant les nouvelles annonces'

    option_list = BaseCommand.option_list + (
                make_option("-n", "--nomail", action="store_true"),
                make_option("-a", "--aujourdhui", action="store_true"),
                make_option("--host"),
           )

    def slice(self, slicable, length):
        i = 0
        while True:
            l = slicable[i:i+length]
            yield l
            if len(l) < length:
                break
            i += length

    @transaction.commit_on_success
    def handle(self, *args, **options):
        logger = middleware.LoggerAdapterWrapper(
                logging.getLogger('logement.cmd'), {})
        logger.info('alertes-annonce avec les options %s', options)
        models.RechercheSauvegardee
        hier = datetime.date.today()
        if not options.get('aujourdhui'):
            hier = hier - datetime.timedelta(days=1)
        annonces = models.Annonce.objects \
                .filter(etat_validation='publiee',
                    derniere_validation__year=hier.year,
                    derniere_validation__month=hier.month,
                    derniere_validation__day=hier.day) \
                .prefetch_related('zones')
        profils_recherches = models.ProfilRecherche.objects.filter(
                recherches_sauvegardees__isnull=False) \
                        .prefetch_related('recherches_sauvegardees',
                                'recherches_sauvegardees__zones')
        jobs = {}
        for sl in self.slice(profils_recherches, 300):
            for pfr in sl:
                matches = set()
                for rs in pfr.recherches_sauvegardees.all():
                    types = rs.filtre_types()
                    zones = set(rs.zones.all())
                    for annonce in annonces:
                        if types and annonce.type_de_logement not in types:
                            continue
                        if rs.intra_muros and annonce.ville.upper() != 'PARIS':
                            continue
                        if not (zones and set(annonce.zones.all())):
                            continue
                        if rs.prix_maximum and annonce.prix_par_mois > rs.prix_maximum:
                            continue
                        if rs.montant_loyer is not None:
                            if rs.montant_loyer == 0 and annonce.prix_par_mois > 500:
                                continue
                            elif rs.montant_loyer == 1 and (annonce.prix_par_mois > 700 or annonce.prix_par_mois < 500):
                                continue
                            elif rs.montant_loyer == 2 and annonce.prix_par_mois < 700:
                                continue
                        if rs.duree_location is not None:
                            if annonce.duree_location is not None and annonce.duree_location != rs.duree_location:
                                continue
                        matches.add(annonce)
                if matches:
                    jobs[pfr.email] = matches
        for email, l in jobs.iteritems():
            print 'Annonces pour', email
            for annonce in l:
                print ' - ', '%s%s' % (options['host'], reverse('recherche-annonce', kwargs=dict(pk=annonce.id)))
            if not options.get('nomail'):
                variables = { 'host': options['host'],
                        'annonces': l }
                try:
                    utils.mail_avec_modele_par_defaut(
                            'Alerte nouvelles annonces',
                            variables,
                            settings.ALERTE_FROM,
                            email)
                except Exception:
                    logger.exception(u"erreur d'envoi d'une alerte à %s", email)
                    continue
            logger.info(u"envoi d'une alerte à %s contenant %s annonces",
                email, len(l))

