#!/usr/bin/env python
# encoding: utf-8
# Copyright 2009 Baptiste Lepilleur and The JsonCpp Authors
# Distributed under MIT license, or public domain if desired and
# recognized in your jurisdiction.
# See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE

from __future__ import print_function
from dircache import listdir
import re
import fnmatch
import os.path


# These fnmatch expressions are used by default to prune the directory tree
# while doing the recursive traversal in the glob_impl method of glob function.
prune_dirs = '.git .bzr .hg .svn _MTN _darcs CVS SCCS '

# These fnmatch expressions are used by default to exclude files and dirs
# while doing the recursive traversal in the glob_impl method of glob function.
##exclude_pats = prune_pats + '*~ #*# .#* %*% ._* .gitignore .cvsignore vssver.scc .DS_Store'.split()

# These ant_glob expressions are used by default to exclude files and dirs and also prune the directory tree
# while doing the recursive traversal in the glob_impl method of glob function.
default_excludes = '''
**/*~
**/#*#
**/.#*
**/%*%
**/._*
**/CVS
**/CVS/**
**/.cvsignore
**/SCCS
**/SCCS/**
**/vssver.scc
**/.svn
**/.svn/**
**/.git
**/.git/**
**/.gitignore
**/.bzr
**/.bzr/**
**/.hg
**/.hg/**
**/_MTN
**/_MTN/**
**/_darcs
**/_darcs/**
**/.DS_Store '''

DIR = 1
FILE = 2
DIR_LINK = 4
FILE_LINK = 8
LINKS = DIR_LINK | FILE_LINK
ALL_NO_LINK = DIR | FILE
ALL = DIR | FILE | LINKS

_ANT_RE = re.compile(r'(/\*\*/)|(\*\*/)|(/\*\*)|(\*)|(/)|([^\*/]*)')

def ant_pattern_to_re(ant_pattern):
    """Generates a regular expression from the ant pattern.
    Matching convention:
    **/a: match 'a', 'dir/a', 'dir1/dir2/a'
    a/**/b: match 'a/b', 'a/c/b', 'a/d/c/b'
    *.py: match 'script.py' but not 'a/script.py'
    """
    rex = ['^']
    next_pos = 0
    sep_rex = r'(?:/|%s)' % re.escape(os.path.sep)
##    print 'Converting', ant_pattern
    for match in _ANT_RE.finditer(ant_pattern):
##        print 'Matched', match.group()
##        print match.start(0), next_pos
        if match.start(0) != next_pos:
            raise ValueError("Invalid ant pattern")
        if match.group(1): # /**/
            rex.append(sep_rex + '(?:.*%s)?' % sep_rex)
        elif match.group(2): # **/
            rex.append('(?:.*%s)?' % sep_rex)
        elif match.group(3): # /**
            rex.append(sep_rex + '.*')
        elif match.group(4): # *
            rex.append('[^/%s]*' % re.escape(os.path.sep))
        elif match.group(5): # /
            rex.append(sep_rex)
        else: # somepath
            rex.append(re.escape(match.group(6)))
        next_pos = match.end()
    rex.append('$')
    return re.compile(''.join(rex))

def _as_list(l):
    if isinstance(l, basestring):
        return l.split()
    return l

def glob(dir_path,
         includes = '**/*',
         excludes = default_excludes,
         entry_type = FILE,
         prune_dirs = prune_dirs,
         max_depth = 25):
    include_filter = [ant_pattern_to_re(p) for p in _as_list(includes)]
    exclude_filter = [ant_pattern_to_re(p) for p in _as_list(excludes)]
    prune_dirs = [p.replace('/',os.path.sep) for p in _as_list(prune_dirs)]
    dir_path = dir_path.replace('/',os.path.sep)
    entry_type_filter = entry_type

    def is_pruned_dir(dir_name):
        for pattern in prune_dirs:
            if fnmatch.fnmatch(dir_name, pattern):
                return True
        return False

    def apply_filter(full_path, filter_rexs):
        """Return True if at least one of the filter regular expression match full_path."""
        for rex in filter_rexs:
            if rex.match(full_path):
                return True
        return False

    def glob_impl(root_dir_path):
        child_dirs = [root_dir_path]
        while child_dirs:
            dir_path = child_dirs.pop()
            for entry in listdir(dir_path):
                full_path = os.path.join(dir_path, entry)
##                print 'Testing:', full_path,
                is_dir = os.path.isdir(full_path)
                if is_dir and not is_pruned_dir(entry): # explore child directory ?
##                    print '===> marked for recursion',
                    child_dirs.append(full_path)
                included = apply_filter(full_path, include_filter)
                rejected = apply_filter(full_path, exclude_filter)
                if not included or rejected: # do not include entry ?
##                    print '=> not included or rejected'
                    continue
                link = os.path.islink(full_path)
                is_file = os.path.isfile(full_path)
                if not is_file and not is_dir:
##                    print '=> unknown entry type'
                    continue
                if link:
                    entry_type = is_file and FILE_LINK or DIR_LINK
                else:
                    entry_type = is_file and FILE or DIR
##                print '=> type: %d' % entry_type,
                if (entry_type & entry_type_filter) != 0:
##                    print ' => KEEP'
                    yield os.path.join(dir_path, entry)
##                else:
##                    print ' => TYPE REJECTED'
    return list(glob_impl(dir_path))


if __name__ == "__main__":
    import unittest

    class AntPatternToRETest(unittest.TestCase):
##        def test_conversion(self):
##            self.assertEqual('^somepath$', ant_pattern_to_re('somepath').pattern)

        def test_matching(self):
            test_cases = [ ('path',
                             ['path'],
                             ['somepath', 'pathsuffix', '/path', '/path']),
                           ('*.py',
                             ['source.py', 'source.ext.py', '.py'],
                             ['path/source.py', '/.py', 'dir.py/z', 'z.pyc', 'z.c']),
                           ('**/path',
                             ['path', '/path', '/a/path', 'c:/a/path', '/a/b/path', '//a/path', '/a/path/b/path'],
                             ['path/', 'a/path/b', 'dir.py/z', 'somepath', 'pathsuffix', 'a/somepath']),
                           ('path/**',
                             ['path/a', 'path/path/a', 'path//'],
                             ['path', 'somepath/a', 'a/path', 'a/path/a', 'pathsuffix/a']),
                           ('/**/path',
                             ['/path', '/a/path', '/a/b/path/path', '/path/path'],
                             ['path', 'path/', 'a/path', '/pathsuffix', '/somepath']),
                           ('a/b',
                             ['a/b'],
                             ['somea/b', 'a/bsuffix', 'a/b/c']),
                           ('**/*.py',
                             ['script.py', 'src/script.py', 'a/b/script.py', '/a/b/script.py'],
                             ['script.pyc', 'script.pyo', 'a.py/b']),
                           ('src/**/*.py',
                             ['src/a.py', 'src/dir/a.py'],
                             ['a/src/a.py', '/src/a.py']),
                           ]
            for ant_pattern, accepted_matches, rejected_matches in list(test_cases):
                def local_path(paths):
                    return [ p.replace('/',os.path.sep) for p in paths ]
                test_cases.append((ant_pattern, local_path(accepted_matches), local_path(rejected_matches)))
            for ant_pattern, accepted_matches, rejected_matches in test_cases:
                rex = ant_pattern_to_re(ant_pattern)
                print('ant_pattern:', ant_pattern, ' => ', rex.pattern)
                for accepted_match in accepted_matches:
                    print('Accepted?:', accepted_match)
                    self.assertTrue(rex.match(accepted_match) is not None)
                for rejected_match in rejected_matches:
                    print('Rejected?:', rejected_match)
                    self.assertTrue(rex.match(rejected_match) is None)

    unittest.main()
