import os, sys
if __name__ == '__main__':
    execfile(os.path.join(sys.path[0], 'framework.py'))

from common import *
from utils import *

from Products.AttachmentField.global_symbols import *

from test_classgen import Dummy as BaseDummy

from os import curdir
from os.path import join, abspath, dirname, split
import os.path

from Products.Archetypes.public import *
from Products.Archetypes.config import PKG_NAME
from Products.Archetypes import listTypes
from Products.Archetypes.utils import DisplayList
from Products.Archetypes import Field
from Products.Archetypes.Field import ScalableImage, Image
from OFS.Image import File
from DateTime import DateTime
from Products.AttachmentField import AttachmentField

import testInterface

import string

try:
    __file__
except NameError:
    # Test was called directly, so no __file__ global exists.
    _prefix = abspath(curdir)
else:
    # Test was called by another test.
    _prefix = abspath(dirname(__file__))

# Raw values
txt_file = open(join(_prefix, 'input', 'rest1.rst'))
txt_content = txt_file.read()

doc_filename = "word.doc"

doc_file = open(join(_prefix, 'input', 'word.doc'))
doc_content = doc_file.read()
doc_preview = open(join(_prefix, 'input', 'word.doc.html')).read()
doc_index = 'quick, i need a word document! headers are nice to have and so is decent data list of things some text'
img_file = open(join(_prefix, 'input', 'tool.gif'))
img_content = img_file.read()

# Flatten index (for test purposes)
def flattenIndex(index):
    words = []
    for w in string.split(index):
        stripped = string.lower(string.strip(w))
        if not stripped in words:
            words.append(stripped)
    words.sort
    return string.join(words, " ")


# Fields definitions
test_fields = {
    "attach_dummy": {
        "filename": "rest1.rst",
        "icon": "text.gif",
        "content_type": "text/plain",
        },
    "attach_txt": {
        "filename": "text.txt",
        "icon": "text.gif",
        "content_type": "text/plain",
        },
    "attach_doc": {
        "filename": "word.doc",
        "icon": "word.gif",
        "content_type": "application/msword",
        },
    "attach_xls": {
        "filename": "excel.xls",
        "icon": "excel.gif",
        "content_type": "application/msexcel",
        },
    }

# Handy structures
field_instances = []
field_values = {}
expected_values = {}
for f, info in test_fields.items():
    # Add the field
    field_instances.append(
        AttachmentField.AttachmentField(f)
        )
    field_values["%s_file" % f] = open(join(_prefix, "input", info["filename"]))
    test_fields[f]['file'] = open(join(_prefix, "input", info["filename"]))

    # Compute raw, index & preview
    file = open(join(_prefix, "input", info["filename"]))
    raw = file.read()
    file.close()
    test_fields[f]["expected"] = raw
    expected_values[f] = info["expected"]
    if os.path.isfile(join(_prefix, "input", info["filename"] + ".index")):
        file = open(join(_prefix, "input", info["filename"] + ".index"))
        index = file.read()
        file.close()
        test_fields[f]["index"] = flattenIndex(index)
    else:
        test_fields[f]["index"] = None
    if os.path.isfile(join(_prefix, "input", info["filename"] + ".html")):
        file = open(join(_prefix, "input", info["filename"] + ".html"))
        preview = file.read()
        file.close()
        test_fields[f]["preview"] = preview
    else:
        test_fields[f]["preview"] = None


schema = BaseDummy.schema + Schema(tuple(field_instances))# + BaseDummy.schema.copy()

class Dummy(BaseDummy):
    schema = schema
    def Title(self): return 'Spam' # required for ImageField
    
##del schema

def gen_dummy():
    gen_class(Dummy, schema)


class FakeRequest:

    def __init__(self):
        self.other = {}
        self.form = {}


from Testing import ZopeTestCase
ZopeTestCase.installProduct('AttachmentField', 1)



class ProcessingTest(ArchetypesTestCase, testInterface.TestInterface):

    klasses = (           # tell which interfaces we check
        AttachmentField.AttachmentField,
        )

    def afterSetUp(self):
        ArchetypesTestCase.afterSetUp(self)
        registerType(Dummy)
        content_types, constructors, ftis = process_types(listTypes(), PKG_NAME)
        gen_dummy()
        self.makeDummy()
        self.fakeUpload()
        
    def makeDummy(self):
        for k, v in test_fields.items():
            v['file'].seek(0)
        self._dummy = Dummy(oid='dummy')
        self._dummy.initializeArchetype()
        return self._dummy


    def fakeUpload(self,):
        dummy = self.makeDummy()
        request = FakeRequest()
        request.form.update(field_values)
        dummy.REQUEST = request
        dummy.processForm(data=1)
        self._content = dummy

    #                                           #
    #                API Testing                #
    #                                           #

    def test_getFilename(self,):
        dummy = self._content
        for k, v in test_fields.items():
            got = dummy.Schema()[k].getFilename(dummy)
            expect = v["filename"]
            self.assertEquals(
                got,
                expect,
                'got: %r, expected: %r, field "%s"' % (got, expect, k),
                )


    def test_getContentType(self,):
        dummy = self._content
        for k, v in test_fields.items():
            got = dummy.Schema()[k].getContentType(dummy)
            expect = v["content_type"]
            self.assertEquals(
                got,
                expect,
                'got: %r, expected: %r, field "%s"' % (got, expect, k),
                )

    def test_getSize(self,):
        dummy = self._content
        for k, v in test_fields.items():
            got = dummy.Schema()[k].getSize(dummy)
            expect = len(v['expected'])
            self.assertEquals(
                got,
                expect,
                'got: %r, expected: %r, field "%s"' % (got, expect, k),
                )

    def test_isEmpty(self,):
        dummy = self._content
        for k, v in test_fields.items():
            got = dummy.Schema()[k].isEmpty(dummy)
            expect = not len(v['expected'])
            self.assertEquals(
                got,
                expect,
                'got: %r, expected: %r, field "%s"' % (got, expect, k),
                )


    def test_getIndexableValue(self, ):
        dummy = self._content
        for k, v in test_fields.items():
            got = dummy.Schema()[k].getIndexableValue(dummy)
            expect = v['index']
            self.assertEquals(
                got,
                expect,
                'got: %r, expected: %r, field "%s"' % (got, expect, k),
                )

    def test_getPreview(self, ):
        dummy = self._content
        for k, v in test_fields.items():
            got = string.strip(dummy.Schema()[k].getPreview(dummy))
            expect = string.strip(str(v['preview']))
            self.assertEquals(
                got,
                expect,
                'got: %r, expected: %r, field "%s"' % (got, expect, k),
                )

    def test_isPreviewAvailable(self,):
        dummy = self._content
        for k, v in test_fields.items():
            got = not not dummy.Schema()[k].isPreviewAvailable(dummy)
            expect = v['preview'] is not None
            self.assertEquals(
                got,
                expect,
                'got: %r, expected: %r, field "%s"' % (got, expect, k),
                )

    def test_isIndexed(self, ):
        dummy = self._content
        for k, v in test_fields.items():
            self.failUnless(
                dummy.Schema()[k].isIndexed(dummy),
                )

    def test_getIcon(self, ):
        # XXX Won't test it until we install the skin in this test case !
        pass
##        dummy = self._content
##        for k, v in test_fields.items():
##            got = dummy.Schema()[k].getIcon(dummy).getId()
##            expect = v['icon']
##            self.assertEquals(
##                got,
##                expect,
##                'got: %r, expected: %r, field "%s"' % (got, expect, k),
##                )

    def test_getSmallIcon(self,):
        """same as getIcon"""
        # XXX Won't test it until we install the skin in this test case !
        pass


    #                                           #
    #           Usual processing                #
    #                                           #
    
    def test_get(self):
        dummy = self.makeDummy()
        request = FakeRequest()
        request.form.update(field_values)
        dummy.REQUEST = request
        dummy.processForm(data=1)
        for k, v in expected_values.items():
            Log(LOG_DEBUG, k)
            got = dummy.Schema()[k].get(dummy)
            if isinstance(got, File):
                got = str(got)
            self.assertEquals(got, v, 'got: %r, expected: %r, field "%s"' %
                              (got, v, k))

    def test_set(self):
        """Same as previous but with fieldsets"""
        dummy = self.makeDummy()
        request = FakeRequest()
        request.form.update(field_values)
        request.form['fieldset'] = 'default'
        dummy.REQUEST = request
        dummy.processForm()
        for k, v in test_fields.items():
            Log(LOG_DEBUG, k)
            got = dummy.Schema()[k].get(dummy)
            if isinstance(got, (File, ScalableImage, Image)):
                got = str(got)
            self.assertEquals(
                got, v['expected'], 'got: %r, expected: %r, field "%s"' %
                (got, v['expected'], k))

    def test_validation(self):
        dummy = self.makeDummy()
        request = FakeRequest()
        request.form.update(field_values)
        request.form['fieldset'] = 'default'
        dummy.REQUEST = request
        errors = {}
        dummy.validate(errors=errors)
        self.failIf(errors, errors)

##    def test_required(self):
##        dummy = self.makeDummy()
##        request = FakeRequest()
##        request.form['fieldset'] = 'default'
##        f_names = []

##        schema = dummy.Schema()
##        for f in schema.fields():
##            name = f.getName()
##            f.required = 1
##            f_names.append(name)
##        errors = {}
##        dummy.validate(REQUEST=request, errors=errors)
##        self.failUnless(errors, "Errors dictionary is empty.")
##        err_fields = errors.keys()
##        failures = []
##        for f_name in f_names:
##            if f_name not in err_fields:
##                failures.append(f_name)
##        self.failIf(failures, "%s failed to report error." % failures)

    def beforeTearDown(self):
        del self._dummy
        ArchetypesTestCase.beforeTearDown(self)




    #                                                                           #
    #                               UNUSEFUL TESTS                              #
    #                                                                           #


    def test_Vocabulary(self,):
        pass

    def test_setStorage(self):
        pass

    def test_getStorage(self,):
        pass

    def test_unset(self,):
        # XXX TODO !!!
        pass

    def test_hasLayer(self,):
        pass

    def test_registerLayer(self):
        pass

    def test_getLayerImpl(self,):
        pass

    def test_registeredLayers(self,):
        pass

    
    

if __name__ == '__main__':
    framework()
else:
    # While framework.py provides its own test_suite()
    # method the testrunner utility does not.
    import unittest
    def test_suite():
        suite = unittest.TestSuite()
        suite.addTest(unittest.makeSuite(ProcessingTest))
        return suite
