# -*- encoding: UTF-8 -*-

from abc import ABCMeta
from django.core.exceptions import ObjectDoesNotExist
from django.conf import settings as st
from cvn.models import (Articulo, Libro, Capitulo, Congreso, Proyecto,
                        Convenio, TesisDoctoral, Patente)
from core.models import UserProfile
from core.ws_utils import CachedWS as ws


class BaseReport:

    __metaclass__ = ABCMeta

    report_type = None

    def __init__(self, generator_cls, year):
        self.year = year
        self.generator = generator_cls(self.year, self.report_type)

    def get_all_units(self):
        # Override this if you want to call create_reports with empty units
        return []

    def get_investigadores(self, unit, title):
        return NotImplemented

    def create_reports(self, units=None):
        if units is None:
            units = self.get_all_units()
        for unit in units:
            self.create_report(unit)

    def create_report(self, unit, title=None):
        try:
            inv, profiles, unit_name = self.get_investigadores(unit, title)
        except UnitDoesNotExist:
            print('WARNING: La unidad ' + str(unit) + ' no existe el año '
                  + str(self.year) + '\n')
            return
        articulos = Articulo.objects.byUsuariosYear(profiles, self.year)
        libros = Libro.objects.byUsuariosYear(profiles, self.year)
        capitulos_libro = Capitulo.objects.byUsuariosYear(profiles, self.year)
        congresos = Congreso.objects.byUsuariosYear(profiles, self.year)
        proyectos = Proyecto.objects.byUsuariosYear(profiles, self.year)
        convenios = Convenio.objects.byUsuariosYear(profiles, self.year)
        tesis = TesisDoctoral.objects.byUsuariosYear(profiles, self.year)
        patentes = Patente.objects.byUsuariosYear(profiles, self.year)
        print('Generando Informe para ' + unit_name + "... ")
        if inv:
            self.generator.go(unit_name, inv,articulos, libros, capitulos_libro,
                              congresos, proyectos, convenios, tesis, patentes)
            print('OK\n')
        else:
            print('ERROR: No hay Investigadores\n')


class ListReport(BaseReport):

    report_type = 'list'

    def get_investigadores(self, unit, title):
        profiles = UserProfile.objects.filter(documento__in=unit)
        investigadores = [{'cod_persona__nombre': p.user.first_name,
                           'cod_persona__apellido1': p.user.last_name,
                           'cod_persona__apellido2': '',
                           'cod_cce__descripcion': ''}
                          for p in profiles]
        if title is None:
            title = ';'.join(unit)
        return investigadores, profiles, title


class UnitReport(BaseReport):

    WS_URL_ALL = None
    WS_URL_DETAIL = None

    def get_all_units(self):
        return map(lambda x: x['codigo'], ws.get(self.WS_URL_ALL))

    def get_investigadores(self, unit, title):
        unit_content = ws.get(self.WS_URL_DETAIL % (unit, self.year))[0]
        if unit_content["unidad"] == {}:
            raise UnitDoesNotExist
        investigadores = []
        usuarios = []
        for inv in unit_content['miembros']:
            inv = self.check_inves(inv)
            investigadores.append(inv)
            try:
                user = UserProfile.objects.get(rrhh_code=inv['cod_persona'])
                usuarios.append(user)
            except ObjectDoesNotExist:
                pass
        if title is None:
            title = unit_content['unidad']['nombre']
        return investigadores, usuarios, title

    @staticmethod
    def check_inves(inv):
        if 'cod_persona__nombre' not in inv:
            inv['cod_persona__nombre'] = ''
        if 'cod_persona__apellido1' not in inv:
            inv['cod_persona__apellido1'] = ''
        if 'cod_persona__apellido2' not in inv:
            inv['cod_persona__apellido2'] = ''
        if 'cod_cce__descripcion' not in inv:
            inv['cod_cce_descripcion'] = ''
        return inv


class DeptReport(UnitReport):
    report_type = 'department'
    WS_URL_ALL = st.WS_DEPARTMENTS_ALL
    WS_URL_DETAIL = st.WS_DEPARTMENTS_AND_MEMBERS_UNIT_YEAR


class AreaReport(UnitReport):
    report_type = 'area'
    WS_URL_ALL = st.WS_AREAS_ALL
    WS_URL_DETAIL = st.WS_AREAS_AND_MEMBERS_UNIT_YEAR


class UnitDoesNotExist(Exception):
    pass
@@ -979,33 +979,16 @@
 =None):%0A
-        try:%0A    
         
@@ -1063,31 +1063,18 @@
     
-except UnitDoesNotExist
+if not inv
 :%0A  
@@ -1089,16 +1089,17 @@
   print(
+u
 'WARNING
@@ -1104,93 +1104,159 @@
 NG: 
-La unidad ' + str(unit) + ' no existe el a%C3%B1o '%0A                  + str(self.year) + '
+No hay Investigadores en la unidad ' + unit_name%0A                  + u' en el a%C3%B1o ' + unicode(self.year)%0A                  + u'. No se generar%C3%A1 informe
 %5Cn')
@@ -1872,16 +1872,17 @@
   print(
+u
 'Generan
@@ -1917,36 +1917,18 @@
 e + 
+u
 %22...
- 
+%5Cn
 %22)%0A
-        if inv:%0A    
     
@@ -2022,28 +2022,24 @@
             
-    
 congresos, p
@@ -2080,100 +2080,8 @@
 es)%0A
-            print('OK%5Cn')%0A        else:%0A            print('ERROR: No hay Investigadores%5Cn')%0A
 %0A%0Acl
@@ -2755,32 +2755,269 @@
 ll_units(self):%0A
+        units = ws.get(self.WS_URL_ALL)%0A        # Save unit names bc the ws doesn't return it when there are no members%0A        self.unit_names = %7B%7D%0A        for unit in units:%0A            self.unit_names%5Bunit%5B'codigo'%5D%5D = unit%5B'nombre'%5D%0A
         return m
@@ -3042,39 +3042,21 @@
 digo'%5D, 
-ws.get(self.WS_URL_ALL)
+units
 )%0A%0A    d
@@ -3228,29 +3228,43 @@
    r
-aise UnitDoesNotExist
+eturn %5B%5D, %5B%5D, self.unit_names%5Bunit%5D
 %0A   
@@ -4433,24 +4433,24 @@
 S_AREAS_ALL%0A
+
     WS_URL_D
@@ -4494,50 +4494,4 @@
 YEAR
-%0A%0A%0Aclass UnitDoesNotExist(Exception):%0A    pass

Save unit name in UnitReport so it can be logged when the unit has no members (in that case the ws doesnt return the name either)