import datetime
import os
from zope.catalog.interfaces import ICatalog
from zope.component import queryUtility, getUtility
from zope.interface.verify import verifyObject, verifyClass
from zope.intid.interfaces import IIntIds
from waeup.kofa.interfaces import ICSVExporter
from waeup.kofa.students.export import (
    StudentsExporter, StudentStudyCourseExporter, StudentStudyLevelExporter,)
from waeup.kofa.students.student import Student, StudentStudyCourse
from waeup.kofa.students.studylevel import StudentStudyLevel
from waeup.kofa.students.tests.test_batching import StudentImportExportSetup
from waeup.kofa.testing import FunctionalLayer

class StudentsExporterTest(StudentImportExportSetup):

    layer = FunctionalLayer

    def setUp(self):
        super(StudentsExporterTest, self).setUp()
        student = Student()
        student.student_id = u'A111111'
        self.app['students'][student.student_id] = self.student = student
        self.outfile = os.path.join(self.workdir, 'myoutput.csv')
        self.cat = getUtility(ICatalog, name='students_catalog')
        self.intids = getUtility(IIntIds)
        return

    def test_ifaces(self):
        # make sure we fullfill interface contracts
        obj = StudentsExporter()
        verifyObject(ICSVExporter, obj)
        verifyClass(ICSVExporter, StudentsExporter)
        return

    def test_get_as_utility(self):
        # we can get an student exporter as utility
        result = queryUtility(ICSVExporter, name="students")
        self.assertTrue(result is not None)
        return

    def setup_student(self, student):
        # set predictable values for `student`
        student.matric_number = u'M123456'
        student.adm_code = u'my adm code'
        student.clearance_locked = False
        student.clr_code = u'my clr code'
        student.perm_address = u'Studentroad 21\nLagos 123456\n'
        student.reg_number = u'123456'
        student.student_id = u'A111111'
        student.firstname = u'Anna'
        student.lastname = u'Tester'
        student.middlename = u'M.'
        student.date_of_birth = datetime.date(1981, 2, 4)
        student.sex = 'f'
        student.email = 'anna@sample.com'
        student.phone = u'+234-123-12345'
        student.notice = u'Some notice\nin lines.'
        student.nationality = u'NG'
        return student

    def test_export(self):
        # we can really export students
        # set values we can expect in export file
        self.setup_student(self.student)
        exporter = StudentsExporter()
        exporter.export([self.student], self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertEqual(
            result,
            'adm_code,clearance_locked,clr_code,date_of_birth,email,employer,'
            'firstname,lastname,matric_number,middlename,nationality,'
            'perm_address,phone,reg_number,sex,student_id\r\n'

            'my adm code,0,my clr code,1981-02-04#,anna@sample.com,,Anna,'
            'Tester,M123456,M.,NG,"Studentroad 21\nLagos 123456\n",'
            '+234-123-12345,123456,f,A111111\r\n'
            )
        return

    def test_export_all(self):
        # we can really export students
        # set values we can expect in export file
        self.setup_student(self.student)
        exporter = StudentsExporter()
        exporter.export_all(self.app, self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertEqual(
            result,
            'adm_code,clearance_locked,clr_code,date_of_birth,email,employer,'
            'firstname,lastname,matric_number,middlename,nationality,'
            'perm_address,phone,reg_number,sex,student_id\r\n'

            'my adm code,0,my clr code,1981-02-04#,anna@sample.com,,Anna,'
            'Tester,M123456,M.,NG,"Studentroad 21\nLagos 123456\n",'
            '+234-123-12345,123456,f,A111111\r\n'
            )
        return

class StudentStudyCourseExporterTest(StudentImportExportSetup):

    layer = FunctionalLayer

    def setUp(self):
        super(StudentStudyCourseExporterTest, self).setUp()
        student = Student()
        student.student_id = u'A111111'
        self.app['students'][student.student_id] = self.student = student
        self.outfile = os.path.join(self.workdir, 'myoutput.csv')
        self.cat = getUtility(ICatalog, name='students_catalog')
        self.intids = getUtility(IIntIds)
        #self.study_course = StudyCourse()
        return

    def test_ifaces(self):
        # make sure we fullfill interface contracts
        obj = StudentStudyCourseExporter()
        verifyObject(ICSVExporter, obj)
        verifyClass(ICSVExporter, StudentStudyCourseExporter)
        return

    def test_get_as_utility(self):
        # we can get an student exporter as utility
        result = queryUtility(ICSVExporter, name="studentstudycourses")
        self.assertTrue(result is not None)
        return

    def setup_student(self, student):
        # set predictable values for `student`
        student.matric_number = u'M123456'
        student.adm_code = u'my adm code'
        student.clearance_locked = False
        student.clr_code = u'my clr code'
        student.perm_address = u'Studentroad 21\nLagos 123456\n'
        student.reg_number = u'123456'
        student.student_id = u'A111111'
        student.firstname = u'Anna'
        student.lastname = u'Tester'
        student.middlename = u'M.'
        student.date_of_birth = datetime.date(1981, 2, 4)
        student.sex = 'f'
        student.email = 'anna@sample.com'
        student.phone = u'+234-123-12345'
        student.notice = u'Some notice\nin lines.'

        study_course = student.get('studycourse')
        student['studycourse'].certificate = self.certificate
        student['studycourse'].entry_mode = 'ug_ft'
        student['studycourse'].entry_session = 2010
        student['studycourse'].current_session = 2012
        student['studycourse'].current_level = int(self.certificate.start_level)
        return student

    def test_export_empty(self):
        # we can export a nearly empty study course
        study_course = StudentStudyCourse()
        exporter = StudentStudyCourseExporter()
        exporter.export([study_course], self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertEqual(
            result,
            'certificate,current_level,current_session,current_verdict,'
            'entry_mode,entry_session,previous_verdict\r\n'

            ',,,0,,,0\r\n'
            )
        return

    def test_export(self):
        # we can really export study courses.
        # set values we can expect in export file
        self.setup_student(self.student)
        study_course = self.student.get('studycourse')
        exporter = StudentStudyCourseExporter()
        exporter.export([study_course], self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertEqual(
            result,
            'certificate,current_level,current_session,current_verdict,'
            'entry_mode,entry_session,previous_verdict\r\n'

            'CERT1,200,2012,0,ug_ft,2010,0\r\n'
            )
        return

    def test_export_all(self):
        # we can really export students
        # set values we can expect in export file
        self.setup_student(self.student)
        exporter = StudentStudyCourseExporter()
        exporter.export_all(self.app, self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertEqual(
            result,
            'certificate,current_level,current_session,current_verdict,'
            'entry_mode,entry_session,previous_verdict\r\n'

            'CERT1,200,2012,0,ug_ft,2010,0\r\n'
            )
        return

class StudentStudyLevelExporterTest(StudentImportExportSetup):

    layer = FunctionalLayer

    def setUp(self):
        super(StudentStudyLevelExporterTest, self).setUp()
        student = Student()
        student.student_id = u'A111111'
        self.app['students'][student.student_id] = self.student = student
        self.outfile = os.path.join(self.workdir, 'myoutput.csv')
        self.cat = getUtility(ICatalog, name='students_catalog')
        self.intids = getUtility(IIntIds)
        #self.study_level = StudyLevel()
        return

    def test_ifaces(self):
        # make sure we fullfill interface contracts
        obj = StudentStudyLevelExporter()
        verifyObject(ICSVExporter, obj)
        verifyClass(ICSVExporter, StudentStudyLevelExporter)
        return

    def test_get_as_utility(self):
        # we can get an student exporter as utility
        result = queryUtility(ICSVExporter, name="studentstudylevels")
        self.assertTrue(result is not None)
        return

    def setup_student(self, student):
        # set predictable values for `student`
        student.matric_number = u'M123456'
        student.adm_code = u'my adm code'
        student.clearance_locked = False
        student.clr_code = u'my clr code'
        student.perm_address = u'Studentroad 21\nLagos 123456\n'
        student.reg_number = u'123456'
        student.student_id = u'A111111'
        student.firstname = u'Anna'
        student.lastname = u'Tester'
        student.middlename = u'M.'
        student.date_of_birth = datetime.date(1981, 2, 4)
        student.sex = 'f'
        student.email = 'anna@sample.com'
        student.phone = u'+234-123-12345'
        student.notice = u'Some notice\nin lines.'

        study_course = student.get('studycourse')
        student['studycourse'].certificate = self.certificate
        student['studycourse'].entry_mode = 'ug_ft'
        student['studycourse'].entry_session = 2010
        student['studycourse'].current_session = 2012
        student['studycourse'].current_level = int(self.certificate.start_level)

        study_level = StudentStudyLevel()
        study_level.level_session = 2012
        study_level.level_verdict = "A"
        study_level.level = 100
        student['studycourse'].addStudentStudyLevel(
            self.certificate, study_level)
        return student

    def test_export_empty(self):
        # we can export a nearly empty study level
        study_level = StudentStudyLevel()
        exporter = StudentStudyLevelExporter()
        exporter.export([study_level], self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertEqual(
            result,
            'level,level_session,level_verdict,matric_number,reg_number\r\n'
            ',,0,,\r\n'
            )
        return

    def test_export(self):
        # we can really export study levels.
        # set values we can expect in export file
        self.setup_student(self.student)
        study_course = self.student.get('studycourse')
        study_level = study_course[study_course.keys()[0]]
        exporter = StudentStudyLevelExporter()
        exporter.export([study_level], self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertEqual(
            result,
            'level,level_session,level_verdict,matric_number,reg_number\r\n'
            '100,2012,A,M123456,123456\r\n'
            )
        return

    def test_export_all(self):
        # we can really export study levels
        # set values we can expect in export file
        self.setup_student(self.student)
        exporter = StudentStudyLevelExporter()
        exporter.export_all(self.app, self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertEqual(
            result,
            'level,level_session,level_verdict,matric_number,reg_number\r\n'
            '100,2012,A,M123456,123456\r\n'
            )
        return
