import collections
import os.path
from zope import component
from zope import interface
from zope.component.factory import Factory
from sparc.configuration import container
import mellon

@interface.implementer(mellon.IByteMellonFile)
class MellonByteFileFromFilePathAndConfig(object):
    
    def __init__(self, file_path, config):
        self.file_path = file_path
        self.config = config
        
    def __str__(self):
        return "byte file at location {}".format(self.file_path)

    def __iter__(self):
        with open(self.file_path, 'rb') as stream:
            file_ = component.createObject(u'mellon.byte_file_from_stream', stream, self.config)
            for snippet in file_:
                yield snippet
mellonByteFileFromFilePathAndConfigFactory = Factory(MellonByteFileFromFilePathAndConfig)

@interface.implementer(mellon.IUnicodeMellonFile)
class MellonUnicodeFileFromFilePathAndConfig(object):
    
    def __init__(self, file_path, config):
        self.file_path = file_path
        self.config = config
        
    def __str__(self):
        return "Unicode file at location {}".format(self.file_path)

    def __iter__(self):
        _end = 0
        _buffer = collections.deque()
        _eof_buffer = collections.deque()
        with open(str(self.file_path), 'rU') as stream:
            file_ = component.createObject(u'mellon.unicode_file_from_stream', stream, self.config)
            for snippet in file_:
                yield snippet
mellonUnicodeFileFromFilePathAndConfigFactory = Factory(MellonUnicodeFileFromFilePathAndConfig)

@interface.implementer(mellon.IMellonFileProvider)
class MellonFileProviderForRecursiveDirectoryConfig(object):
    
    def __init__(self, config):
        """Init
        
        Args:
            config: sparc.configuration.container.ISparcAppPyContainerConfiguration
                    provider with 
                    mellon.factories.filesystem[configure.yaml:FileSystemDir]
                    and mellon[configure.yaml:MellonSnippet] entries.
        """
        self.config = config
    
    def __iter__(self):
        base_path = container.IPyContainerConfigValue(self.config).\
                                            get('FileSystemDir')['directory']
        for d, dirs, files in os.walk(base_path):
            for f in files:
                path = os.path.join(d, f)
                if not os.path.isfile(path):
                    continue
                #get interface-assigned string (IPath)
                path = component.createObject(u'mellon.filesystem_path', path)
                if mellon.IBinaryChecker(path).check():
                    yield component.createObject(\
                        u'mellon.factories.filesystem.byte_file', path, self.config)
                else:
                    yield component.createObject(\
                        u'mellon.factories.filesystem.unicode_file', path, self.config)
    
mellonFileProviderForRecursiveDirectoryConfigFactory = Factory(MellonFileProviderForRecursiveDirectoryConfig)
interface.alsoProvides(mellonFileProviderForRecursiveDirectoryConfigFactory, mellon.IMellonFileProviderFactory)

[((189, 234), 'zope.interface.implementer', 'interface.implementer', (['mellon.IByteMellonFile'], {}), '(mellon.IByteMellonFile)\n', (210, 234), False, 'from zope import interface\n'), ((777, 821), 'zope.component.factory.Factory', 'Factory', (['MellonByteFileFromFilePathAndConfig'], {}), '(MellonByteFileFromFilePathAndConfig)\n', (784, 821), False, 'from zope.component.factory import Factory\n'), ((824, 872), 'zope.interface.implementer', 'interface.implementer', (['mellon.IUnicodeMellonFile'], {}), '(mellon.IUnicodeMellonFile)\n', (845, 872), False, 'from zope import interface\n'), ((1529, 1576), 'zope.component.factory.Factory', 'Factory', (['MellonUnicodeFileFromFilePathAndConfig'], {}), '(MellonUnicodeFileFromFilePathAndConfig)\n', (1536, 1576), False, 'from zope.component.factory import Factory\n'), ((1579, 1628), 'zope.interface.implementer', 'interface.implementer', (['mellon.IMellonFileProvider'], {}), '(mellon.IMellonFileProvider)\n', (1600, 1628), False, 'from zope import interface\n'), ((2991, 3045), 'zope.component.factory.Factory', 'Factory', (['MellonFileProviderForRecursiveDirectoryConfig'], {}), '(MellonFileProviderForRecursiveDirectoryConfig)\n', (2998, 3045), False, 'from zope.component.factory import Factory\n'), ((3046, 3161), 'zope.interface.alsoProvides', 'interface.alsoProvides', (['mellonFileProviderForRecursiveDirectoryConfigFactory', 'mellon.IMellonFileProviderFactory'], {}), '(mellonFileProviderForRecursiveDirectoryConfigFactory,\n    mellon.IMellonFileProviderFactory)\n', (3068, 3161), False, 'from zope import interface\n'), ((1199, 1218), 'collections.deque', 'collections.deque', ([], {}), '()\n', (1216, 1218), False, 'import collections\n'), ((1241, 1260), 'collections.deque', 'collections.deque', ([], {}), '()\n', (1258, 1260), False, 'import collections\n'), ((591, 667), 'zope.component.createObject', 'component.createObject', (['u"""mellon.byte_file_from_stream"""', 'stream', 'self.config'], {}), "(u'mellon.byte_file_from_stream', stream, self.config)\n", (613, 667), False, 'from zope import component\n'), ((1337, 1416), 'zope.component.createObject', 'component.createObject', (['u"""mellon.unicode_file_from_stream"""', 'stream', 'self.config'], {}), "(u'mellon.unicode_file_from_stream', stream, self.config)\n", (1359, 1416), False, 'from zope import component\n'), ((2522, 2577), 'zope.component.createObject', 'component.createObject', (['u"""mellon.filesystem_path"""', 'path'], {}), "(u'mellon.filesystem_path', path)\n", (2544, 2577), False, 'from zope import component\n'), ((2123, 2169), 'sparc.configuration.container.IPyContainerConfigValue', 'container.IPyContainerConfigValue', (['self.config'], {}), '(self.config)\n', (2156, 2169), False, 'from sparc.configuration import container\n'), ((2597, 2624), 'mellon.IBinaryChecker', 'mellon.IBinaryChecker', (['path'], {}), '(path)\n', (2618, 2624), False, 'import mellon\n'), ((2660, 2748), 'zope.component.createObject', 'component.createObject', (['u"""mellon.factories.filesystem.byte_file"""', 'path', 'self.config'], {}), "(u'mellon.factories.filesystem.byte_file', path, self\n    .config)\n", (2682, 2748), False, 'from zope import component\n'), ((2818, 2908), 'zope.component.createObject', 'component.createObject', (['u"""mellon.factories.filesystem.unicode_file"""', 'path', 'self.config'], {}), "(u'mellon.factories.filesystem.unicode_file', path,\n    self.config)\n", (2840, 2908), False, 'from zope import component\n')]