import datetime
from zope.component import queryUtility
from zope.interface.verify import verifyObject, verifyClass
from waeup.kofa.interfaces import ICSVExporter
from waeup.kofa.students.export import (
    StudentsExporter, StudentStudyCourseExporter, StudentStudyLevelExporter,
    CourseTicketExporter, PaymentsExporter)
from waeup.kofa.students.payments import StudentOnlinePayment
from waeup.kofa.students.studycourse import StudentStudyCourse
from waeup.kofa.students.studylevel import StudentStudyLevel, CourseTicket
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()
        self.setup_for_export()
        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 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.assertTrue(
            '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,password,'
            'state,history,certcode\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,,created'
            in result
            )
        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.assertTrue(
            '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,password,'
            'state,history,certcode\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,,created'
            in result
            )
        return

    def test_export_student(self):
        # we can export a single student
        self.setup_student(self.student)
        exporter = StudentsExporter()
        exporter.export_student(self.student, self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertTrue(
            '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,password,'
            'state,history,certcode\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,,created'
            in result
            )
        return


class StudentStudyCourseExporterTest(StudentImportExportSetup):

    layer = FunctionalLayer

    def setUp(self):
        super(StudentStudyCourseExporterTest, self).setUp()
        self.setup_for_export()
        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 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,student_id\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,student_id\r\n'

            'CERT1,200,2012,0,ug_ft,2010,0,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 = 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,student_id\r\n'

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

    def test_export_student(self):
        # we can export studycourse of a certain student
        self.setup_student(self.student)
        exporter = StudentStudyCourseExporter()
        exporter.export_student(self.student, self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertEqual(
            result,
            'certificate,current_level,current_session,current_verdict,'
            'entry_mode,entry_session,previous_verdict,student_id\r\n'

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

class StudentStudyLevelExporterTest(StudentImportExportSetup):

    layer = FunctionalLayer

    def setUp(self):
        super(StudentStudyLevelExporterTest, self).setUp()
        self.setup_for_export()
        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 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,student_id\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,student_id\r\n'
            '100,2012,A,A111111\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,student_id\r\n'
            '100,2012,A,A111111\r\n'
            )
        return

    def test_export_student(self):
        # we can really export study levels of a certain student
        self.setup_student(self.student)
        exporter = StudentStudyLevelExporter()
        exporter.export_student(self.student, self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertEqual(
            result,
            'level,level_session,level_verdict,student_id\r\n'
            '100,2012,A,A111111\r\n'
            )
        return

class CourseTicketExporterTest(StudentImportExportSetup):

    layer = FunctionalLayer

    def setUp(self):
        super(CourseTicketExporterTest, self).setUp()
        self.setup_for_export()
        return

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

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

    def test_export_empty(self):
        # we can export a nearly empty course ticket
        ticket = CourseTicket()
        exporter = CourseTicketExporter()
        exporter.export([ticket], self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertEqual(
            result,
            'automatic,carry_over,code,credits,dcode,fcode,level,mandatory,'
            'passmark,score,semester,title,student_id\r\n'
            '0,0,,,,,,0,,0,,,\r\n'
            )
        return

    def test_export(self):
        # we can really export course tickets.
        # 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]]
        ticket = study_level['CRS1']
        exporter = CourseTicketExporter()
        exporter.export([ticket], self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertEqual(
            result,
            'automatic,carry_over,code,credits,dcode,fcode,level,mandatory,'
            'passmark,score,semester,title,student_id\r\n'
            '1,1,CRS1,100,DEP1,FAC1,100,0,100,0,2,Course 1,A111111\r\n'
            )
        return

    def test_export_all(self):
        # we can really export all course tickets
        # set values we can expect in export file
        self.setup_student(self.student)
        exporter = CourseTicketExporter()
        exporter.export_all(self.app, self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertEqual(
            result,
            'automatic,carry_over,code,credits,dcode,fcode,level,mandatory,'
            'passmark,score,semester,title,student_id\r\n'
            '1,1,CRS1,100,DEP1,FAC1,100,0,100,0,2,Course 1,A111111\r\n'
            )
        return

    def test_export_student(self):
        # we can really export all course tickets of a certain student
        self.setup_student(self.student)
        exporter = CourseTicketExporter()
        exporter.export_student(self.student, self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertEqual(
            result,
            'automatic,carry_over,code,credits,dcode,fcode,level,mandatory,'
            'passmark,score,semester,title,student_id\r\n'
            '1,1,CRS1,100,DEP1,FAC1,100,0,100,0,2,Course 1,A111111\r\n'
            )
        return

class PaymentsExporterTest(StudentImportExportSetup):

    layer = FunctionalLayer

    def setUp(self):
        super(PaymentsExporterTest, self).setUp()
        self.setup_for_export()
        return

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

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

    def test_export_empty(self):
        # we can export a nearly empty payment
        payment = StudentOnlinePayment()
        payment.creation_date = datetime.datetime(2012, 4, 1, 13, 12, 1)
        exporter = PaymentsExporter()
        exporter.export([payment], self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertEqual(
            result,
            'ac,amount_auth,creation_date,p_category,p_id,'
            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
            'r_code,r_desc,student_id\r\n'

            ',0.0,2012-04-01 13:12:01,schoolfee,,,,,unpaid,,0.0,,,\r\n'
            )
        return

    def test_export(self):
        # we can really export student payments.
        # set values we can expect in export file
        self.setup_student(self.student)
        payment = self.student['payments']['my-payment']
        exporter = PaymentsExporter()
        exporter.export([payment], self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertEqual(
            result,
            'ac,amount_auth,creation_date,p_category,p_id,'
            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
            'r_code,r_desc,student_id\r\n'

            '666,0.0,2012-04-01 13:12:01,schoolfee,my-id,'
            'p-item,100,2012,unpaid,2012-04-01 14:12:01,12.12,'
            'r-code,,A111111\r\n'
            )
        return

    def test_export_all(self):
        # we can really export all payments
        # set values we can expect in export file
        self.setup_student(self.student)
        exporter = PaymentsExporter()
        exporter.export_all(self.app, self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertEqual(
            result,
            'ac,amount_auth,creation_date,p_category,p_id,'
            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
            'r_code,r_desc,student_id\r\n'

            '666,0.0,2012-04-01 13:12:01,schoolfee,my-id,'
            'p-item,100,2012,unpaid,2012-04-01 14:12:01,12.12,'
            'r-code,,A111111\r\n'
            )
        return

    def test_export_student(self):
        # we can really export all payments of a certain student
        # set values we can expect in export file
        self.setup_student(self.student)
        exporter = PaymentsExporter()
        exporter.export_student(self.student, self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertEqual(
            result,
            'ac,amount_auth,creation_date,p_category,p_id,'
            'p_item,p_level,p_session,p_state,payment_date,r_amount_approved,'
            'r_code,r_desc,student_id\r\n'

            '666,0.0,2012-04-01 13:12:01,schoolfee,my-id,'
            'p-item,100,2012,unpaid,2012-04-01 14:12:01,12.12,'
            'r-code,,A111111\r\n'
            )
        return
