#-*- mode: python; mode: fold -*-
from Globals import InitializeClass
from AccessControl import ClassSecurityInfo

from Products.CMFCore.utils import UniqueObject, getToolByName
from Products.CMFCore.permissions import View
from Products.CMFCore.permissions import ModifyPortalContent
from Products.CPSCore.CPSBase import CPSBase_adder, CPSBaseFolder
#from Products.CPSCore.CPSBase import CPSBaseDocument as BaseDocument
from Products.CPSDocument.CPSDocument import CPSDocument
from Products.CPSCore.CPSBase import CPSBaseBTreeFolder as BaseBTreeFolder
from Products.WAeUP_SRP.WAeUPTables import AccommodationTable
import logging
import csv,re,os
import Globals
import DateTime
import re
p_home = Globals.package_home(globals())
i_home = Globals.INSTANCE_HOME

class AccoFolder(CPSDocument): ###(
    """
    WAeUP AccoFolder containing Accommodation halls
    """
    meta_type = 'AccoFolder'
    portal_type = meta_type
    security = ClassSecurityInfo()

    security.declareProtected(View,"Title")
    def Title(self):
        """compose title"""
        return "Accommodation Section"

    security.declareProtected(ModifyPortalContent,"generateFreeBedsList") ###(
    def generateFreeBedsList(self):
        """
        generate the free Bedslist.
        """
        freelist = self.portal_accommodation
        l = self.portal_catalog({'meta_type': "AccoHall"})
        halls = []
        generated = []
        generated.append('"Bed","BedType","Student"' % vars())
        beds_generated = []
        for h in l:
            halls.append(h.getObject())
        for hall in halls:
            #import pdb;pdb.set_trace()
            h = hall.getContent()
            hall_gen = {}
            hall_gen['name'] = hall.Title
            count = 0
            reserved = [(r.split('/')[0],int(r.split('/')[1])) for r in re.split(',|\.| ',h.reserved_rooms)
                                     if r]
            #for block in range(1,int(h.nr_of_blocks)+1):
            for block in 'ABCDEFGHIJ'[:int(h.nr_of_blocks)]:
                sex = 'male'
                if block in h.blocks_for_female:
                    sex = 'female'
                for floor in range(1,int(h.nr_of_floors)+1):
                    for room in range(1,int(h.rooms_per_floor)+1):
                        for bed in 'ABCDEFGH'[:int(h.beds_per_room)]:
                            room_nr = floor*100 + room
                            bt = 're'
                            if (block,room_nr) in reserved:
                                bt = "reserved"
                            elif not h.special_handling.startswith("no"):
                                bt = h.special_handling
                            elif bed in h.beds_for_fresh:
                                bt = 'fr'
                            #elif bed in h.beds_for_returning:
                            #    bt = 're'
                            elif bed in h.beds_for_final:
                                bt = 'fi'
                            if h.special_handling.startswith("no_"):
                                bt += "_" + h.special_handling[3:]
                            bt = "%(sex)s_%(bt)s" % vars()
                            uid = '%s_%s_%d_%s' % (hall.getId(),block,room_nr,bed)
                            try:
                                freelist.addRecord(bed = uid, bed_type = bt,hall = hall.getId())
                                count +=1
                                generated.append('"%(uid)s","%(bt)s"' % vars())
                            except ValueError:
                                #freelist.modifyRecord(bed = uid, bed_type = bt,hall =hall.getId())
                                pass
            hall_gen['count']= count
            beds_generated.append(hall_gen)
        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
        open("%s/import/bedlist_%s.csv" % (i_home,current),"w+").write('\n'.join(generated))
        return self.accommodation.acco_folder_view(beds_generated=beds_generated)

###)

    security.declareProtected(ModifyPortalContent,"importReservedBeds")###(
    def importReservedBeds(self):
        """load Reserved Beds from CSV"""
        import transaction
        import random
        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
        students_folder = self.portal_url.getPortalObject().campus.students
        acco_folder = self.portal_url.getPortalObject().campus.accommodation
        tr_count = 1
        total = 0
        name = 'ReservedBeds'
        accommodation = self.portal_accommodation
        students_cat = self.students_catalog
        no_import = []
        imported = []
        logger = logging.getLogger('Accommodation.AccoFolder.importReservedBeds')
        try:
            beds = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
        except:
            logger.error('Error reading %s.csv' % name)
            return
        halls = {}
        start = True
        for bed in beds:
            if start:
                start = False
                logger.info('start loading from %s.csv' % name)
                s = ','.join(['"%s"' % fn for fn in bed.keys()])
                imported.append(s)
                no_import.append('%s,"Error"' % s)
                format = ','.join(['"%%(%s)s"' % fn for fn in bed.keys()])
                format_error = format + ',"%(Error)s"'
                no_certificate = "no certificate %s" % format
            matric_no = bed.get('matric_no')
            jamb_reg_no = bed.get('jamb_reg_no')
            if matric_no != '':
                res = students_cat(matric_no = matric_no)
                if not res:
                    bed['Error'] = "No such student"
                    no_import.append( format_error % bed)
                    continue
                student = res[0]
            elif jamb_reg_no != '':
                res = students_cat(jamb_reg_no = jamb_reg_no)
                if not res:
                    bed['Error'] = "No such student"
                    no_import.append( format_error % bed)
                    continue
                student = res[0]
            else:
                bed['Error'] = "No such student"
                no_import.append( format_error % bed)
                continue
            sid = student.id
            names = bed.get('name').split()
            n = 0
            for na in names:
                if na.endswith(','):
                    names[n] = na[:-1]
                n += 1
            s_names = student.name.split()
            found = False
            for sn in s_names:
                if sn.upper() in names:
                    found = True
                    break
            if not found:
                bed['Error'] = "Name mismatch %s %s" % (str(names),str(s_names))
                no_import.append( format_error % bed)
                continue
            hall = bed.get('hall')
            if hall not in halls.keys():
                hall_object = getattr(acco_folder,hall, None)
                if hall_object is None:
                    bed['Error'] = "No such hall"
                    no_import.append( format_error % bed)
                    continue
                halls[hall] = hall_doc = hall_object.getContent()
            bid = "%(hall)s_%(block)s_%(room)s_%(bed)s" % bed
            res = accommodation(bed = bid)
            psm = ''
            while True:
                if not res:
                    psm = "No bed with this id"
                    break
                bed_brain = res[0]
                if not bed_brain.bed_type.endswith("reserved"):
                    psm = "Not a reserved bed"
                    break
                if bed_brain.student:
                    psm = "Bed %s already reserved for %s" % (bid,bed_brain.student)
                    break
                if student.sex and not bed.get('block') in hall_doc.blocks_for_female:
                    psm = "Sex does not match %s" % bid
                    break
                break
            if psm != '':
                bed['Error'] = psm
                no_import.append( format_error % bed)
                continue
            already = accommodation(student=sid)
            if already:
                accommodation.modifyRecord(bed=already[0].bed,student='')
                student_obj = getattr(students_folder, student.id)
                acco_id = "accommodation_%s" % self.getSessionId()
                if acco_id in student_obj.objectIds():
                    acco_doc = getattr(student_obj, acco_id).getContent()
                    acco_doc.edit(mapping={'bed': bid})
                    member = self.portal_membership.getAuthenticatedMember()
                    logger.info('%s changed reserved bed %s for %s' % (member,bid,sid))
            accommodation.modifyRecord(bed = bid, student = sid)
            imported.append( format % bed)
            tr_count += 1
            if tr_count > 1000:
                if len(no_import) > 0:
                    open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
                             '\n'.join(no_import) + '\n')
                    no_import = []
                open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
                                            '\n'.join(no_import) + "\n")
                imported = []
                em = '%d transactions commited total %s\n' % (tr_count,total)
                transaction.commit()
                regs = []
                logger.info(em)
                total += tr_count
                tr_count = 0
        #from pdb import set_trace;set_trace()
        open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
                                            '\n'.join(imported))
        open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
                                                '\n'.join(no_import))
        logger.info('finished loading from %s.csv' % name)
        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))


InitializeClass(AccoFolder)

def addAccoFolder(container, id, REQUEST=None, **kw):
    """Add a AccoFolder."""
    ob = AccoFolder(id, **kw)
    return CPSBase_adder(container, ob, REQUEST=REQUEST)
###)

class AccoHall(CPSDocument): ###(
    """
    WAeUP AccoHall containing Departments
    """
    meta_type = 'AccoHall'
    portal_type = meta_type
    security = ClassSecurityInfo()

    security.declareProtected(View,"Title") ###(
    def Title(self):
        """compose title"""
        content = self.getContent()
        heading = getattr(content,'heading',None)
        if heading is None:
            return self.title
        return heading
    ###)

InitializeClass(AccoHall)


def addAccoHall(container, id, REQUEST=None, **kw):
    """Add a AccoHall."""
    ob = AccoHall(id, **kw)
    return CPSBase_adder(container, ob, REQUEST=REQUEST)
###)
