#! /usr/bin/env python
import os
import pprint
import re
from abjad import abjad_configuration
from abjad.tools import systemtools


directory_name_blacklist = (
    'demos',
    )

file_name_blacklist = (
    'ez_setup.py',
    'getters.py',
    'predicates.py',
    'setup.py',
    )

class_definition_pattern = re.compile(r'\s*class\s+(\w+)')
function_definition_pattern = re.compile(r'\s*def\s+(\w+)')

def find_multifunction_modules():

    multifunction_modules = []
    for directory_path, subdirectory_names, file_names in os.walk('.'):
        subdirectory_names_to_remove = []
        for subdirectory_name in subdirectory_names:
            if subdirectory_name in directory_name_blacklist:
                subdirectory_names_to_remove.append(subdirectory_name)
        for subdirectory_name in subdirectory_names_to_remove:
            subdirectory_names.remove(subdirectory_name)
        for file_name in file_names:
            if file_name.endswith('.py') and \
                file_name not in file_name_blacklist:
                if not file_name.startswith('test_'):
                    result = has_multiple_public_function_definitions(
                        directory_path,
                        file_name
                        )
                    if result:
                        file_path = os.path.join(directory_path, file_name)
                        result_pair = (file_path, result)
                        multifunction_modules.append(result_pair)

    total = len(multifunction_modules)
    if total:
        print 'Printing modles with multiple public functions ...'
        print
        for module_name, function_names in multifunction_modules:
            print module_name
            for function_name in function_names:
                print '\t' + function_name
            print

    print 'Total modules with multiple public functions: {}'.format(total)
    print


def has_multiple_public_function_definitions(path, file_name):
    function_names = []
    full_name = os.path.join(path, file_name)
    for line in file(full_name, 'r').readlines():
        match = class_definition_pattern.match(line)
        if match is not None:
            return False
        match = function_definition_pattern.match(line)
        if match is not None:
            function_name = match.groups()[0]
            if not function_name.startswith('_'):
                function_names.append(function_name)
    if 1 < len(function_names):
        return function_names
    else:
        return False


if __name__ == '__main__':
    systemtools.IOManager.clear_terminal()
    find_multifunction_modules()
