import os
import grok
import datetime
from cStringIO import StringIO
from zope.component import queryUtility, getUtility
from zope.event import notify
from zope.interface.verify import verifyObject, verifyClass
from waeup.ikoba.interfaces import (
    ICSVExporter, IExtFileStore, IFileStoreNameChooser)
from waeup.ikoba.customers.catalog import CustomersQuery
from waeup.ikoba.customers.export import (
    CustomersExporter, CustomerDocumentsExporter, get_customers)
from waeup.ikoba.customers.interfaces import ICSVCustomerExporter
from waeup.ikoba.customers.customer import Customer
from waeup.ikoba.customers.documents import CustomerDocument
from waeup.ikoba.customers.tests.test_batching import CustomerImportExportSetup
from waeup.ikoba.testing import FunctionalLayer

curr_year = datetime.datetime.now().year
year_range = range(curr_year - 9, curr_year + 1)
year_range_str = ','.join([str(i) for i in year_range])

class ExportHelperTests(CustomerImportExportSetup):
    layer = FunctionalLayer
    def setUp(self):
        super(ExportHelperTests, self).setUp()
        customer = Customer()
        self.app['customers'].addCustomer(customer)
        customer = self.setup_customer(customer)
        notify(grok.ObjectModifiedEvent(customer))
        self.customer = self.app['customers'][customer.customer_id]
        return

    def test_get_customers_plain(self):
        # without a filter we get all customers
        result = get_customers(self.app)
        self.assertEqual(len(list(result)), 1)
        return

class CustomersExporterTest(CustomerImportExportSetup):

    layer = FunctionalLayer

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

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

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

    def test_export(self):
        # we can really export customers
        # set values we can expect in export file
        self.setup_customer(self.customer)
        exporter = CustomersExporter()
        exporter.export([self.customer], self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertTrue(
            'customer_id,email,firstname,lastname,middlename,phone,'
            'reg_number,sex,suspended,suspended_comment,password,state,'
            'history\r\n'
            'A111111,anna@sample.com,Anna,Tester,M.,+234-123-12345#,'
            '123,,0,,,created'
            in result
            )
        return

    def test_export_all(self):
        # we can really export customers
        # set values we can expect in export file
        self.setup_customer(self.customer)
        exporter = CustomersExporter()
        exporter.export_all(self.app, self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertTrue(
            'customer_id,email,firstname,lastname,middlename,phone,'
            'reg_number,sex,suspended,suspended_comment,password,state,history\r\n'
            'A111111,anna@sample.com,Anna,Tester,M.,+234-123-12345#,'
            '123,,0,,,created'
            in result
            )
        return

    def test_export_customer(self):
        # we can export a single customer
        self.setup_customer(self.customer)
        exporter = CustomersExporter()
        exporter.export_customer(self.customer, self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertTrue(
            'customer_id,email,firstname,lastname,middlename,phone,reg_number,'
            'sex,suspended,suspended_comment,password,state,history\r\n'
            'A111111,anna@sample.com,Anna,Tester,M.,+234-123-12345#,'
            '123,,0,,,created,'
            in result
            )
        return

class CustomerDocumentsExporterTest(CustomerImportExportSetup):

    layer = FunctionalLayer

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

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

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

    def test_export_empty(self):
        # we can export a nearly empty document
        document = CustomerDocument()
        exporter = CustomerDocumentsExporter()
        exporter.export([document], self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertEqual(
            result,
            'document_id,history,state,title,customer_id\r\n'
            'd101,[],,,\r\n'
            )
        return

    def test_export(self):
        # we can really export customer documents.
        # set values we can expect in export file
        self.setup_customer(self.customer)
        document = self.customer['documents']['d101']
        exporter = CustomerDocumentsExporter()
        exporter.export([document], self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertTrue(
            'document_id,history,state,title,customer_id\r\n'
            in result
            )
        self.assertTrue(
            'Document created by system\'],created,My Document,A111111\r\n'
            in result
            )
        return

    def test_export_all(self):
        # we can really export all documents
        # set values we can expect in export file
        self.setup_customer(self.customer)
        exporter = CustomerDocumentsExporter()
        exporter.export_all(self.app, self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertTrue(
            'document_id,history,state,title,customer_id\r\n'
            in result)
        self.assertTrue(
            ' Document created by system\'],created,My Document,A111111\r\n'
            in result)
        return

    def test_export_customer(self):
        # we can really export all documents of a certain customer
        # set values we can expect in export file
        self.setup_customer(self.customer)
        exporter = CustomerDocumentsExporter()
        exporter.export_customer(self.customer, self.outfile)
        result = open(self.outfile, 'rb').read()
        self.assertTrue(
            'document_id,history,state,title,customer_id\r\n'
            in result)
        self.assertTrue(
            ' Document created by system\'],created,My Document,A111111\r\n'
            in result)
        return
