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)

[((9, 1, 9, 46), 'zope.interface.implementer', 'interface.implementer', ({(9, 23, 9, 45): 'mellon.IByteMellonFile'}, {}), '(mellon.IByteMellonFile)', False, 'from zope import interface\n'), ((24, 45, 24, 89), 'zope.component.factory.Factory', 'Factory', ({(24, 53, 24, 88): 'MellonByteFileFromFilePathAndConfig'}, {}), '(MellonByteFileFromFilePathAndConfig)', False, 'from zope.component.factory import Factory\n'), ((26, 1, 26, 49), 'zope.interface.implementer', 'interface.implementer', ({(26, 23, 26, 48): 'mellon.IUnicodeMellonFile'}, {}), '(mellon.IUnicodeMellonFile)', False, 'from zope import interface\n'), ((44, 48, 44, 95), 'zope.component.factory.Factory', 'Factory', ({(44, 56, 44, 94): 'MellonUnicodeFileFromFilePathAndConfig'}, {}), '(MellonUnicodeFileFromFilePathAndConfig)', False, 'from zope.component.factory import Factory\n'), ((46, 1, 46, 50), 'zope.interface.implementer', 'interface.implementer', ({(46, 23, 46, 49): 'mellon.IMellonFileProvider'}, {}), '(mellon.IMellonFileProvider)', False, 'from zope import interface\n'), ((77, 55, 77, 109), 'zope.component.factory.Factory', 'Factory', ({(77, 63, 77, 108): 'MellonFileProviderForRecursiveDirectoryConfig'}, {}), '(MellonFileProviderForRecursiveDirectoryConfig)', False, 'from zope.component.factory import Factory\n'), ((78, 0, 78, 111), 'zope.interface.alsoProvides', 'interface.alsoProvides', ({(78, 23, 78, 75): 'mellonFileProviderForRecursiveDirectoryConfigFactory', (78, 77, 78, 110): 'mellon.IMellonFileProviderFactory'}, {}), '(mellonFileProviderForRecursiveDirectoryConfigFactory,\n    mellon.IMellonFileProviderFactory)', False, 'from zope import interface\n'), ((38, 18, 38, 37), 'collections.deque', 'collections.deque', ({}, {}), '()', False, 'import collections\n'), ((39, 22, 39, 41), 'collections.deque', 'collections.deque', ({}, {}), '()', False, 'import collections\n'), ((21, 20, 21, 96), 'zope.component.createObject', 'component.createObject', ({(21, 43, 21, 74): 'u"""mellon.byte_file_from_stream"""', (21, 76, 21, 82): 'stream', (21, 84, 21, 95): 'self.config'}, {}), "(u'mellon.byte_file_from_stream', stream, self.config)", False, 'from zope import component\n'), ((41, 20, 41, 99), 'zope.component.createObject', 'component.createObject', ({(41, 43, 41, 77): 'u"""mellon.unicode_file_from_stream"""', (41, 79, 41, 85): 'stream', (41, 87, 41, 98): 'self.config'}, {}), "(u'mellon.unicode_file_from_stream', stream, self.config)", False, 'from zope import component\n'), ((69, 23, 69, 78), 'zope.component.createObject', 'component.createObject', ({(69, 46, 69, 71): 'u"""mellon.filesystem_path"""', (69, 73, 69, 77): 'path'}, {}), "(u'mellon.filesystem_path', path)", False, 'from zope import component\n'), ((61, 20, 61, 66), 'sparc.configuration.container.IPyContainerConfigValue', 'container.IPyContainerConfigValue', ({(61, 54, 61, 65): 'self.config'}, {}), '(self.config)', False, 'from sparc.configuration import container\n'), ((70, 19, 70, 46), 'mellon.IBinaryChecker', 'mellon.IBinaryChecker', ({(70, 41, 70, 45): 'path'}, {}), '(path)', False, 'import mellon\n'), ((71, 26, 72, 84), 'zope.component.createObject', 'component.createObject', ({(72, 24, 72, 64): 'u"""mellon.factories.filesystem.byte_file"""', (72, 66, 72, 70): 'path', (72, 72, 72, 83): 'self.config'}, {}), "(u'mellon.factories.filesystem.byte_file', path, self\n    .config)", False, 'from zope import component\n'), ((74, 26, 75, 87), 'zope.component.createObject', 'component.createObject', ({(75, 24, 75, 67): 'u"""mellon.factories.filesystem.unicode_file"""', (75, 69, 75, 73): 'path', (75, 75, 75, 86): 'self.config'}, {}), "(u'mellon.factories.filesystem.unicode_file', path,\n    self.config)", False, 'from zope import component\n')]