from __future__ import nested_scopes

import fnmatch
import os.path
from pydev_runfiles_coverage import StartCoverageSupport
from pydevd_constants import * #@UnusedWildImport
import re
import time


#=======================================================================================================================
# Configuration
#=======================================================================================================================
class Configuration:

    def __init__(
        self,
        files_or_dirs='',
        verbosity=2,
        include_tests=None,
        tests=None,
        port=None,
        files_to_tests=None,
        jobs=1,
        split_jobs='tests',
        coverage_output_dir=None,
        coverage_include=None,
        coverage_output_file=None,
        exclude_files=None,
        exclude_tests=None,
        include_files=None,
        django=False,
        ):
        self.files_or_dirs = files_or_dirs
        self.verbosity = verbosity
        self.include_tests = include_tests
        self.tests = tests
        self.port = port
        self.files_to_tests = files_to_tests
        self.jobs = jobs
        self.split_jobs = split_jobs
        self.django = django

        if include_tests:
            assert isinstance(include_tests, (list, tuple))

        if exclude_files:
            assert isinstance(exclude_files, (list, tuple))

        if exclude_tests:
            assert isinstance(exclude_tests, (list, tuple))

        self.exclude_files = exclude_files
        self.include_files = include_files
        self.exclude_tests = exclude_tests

        self.coverage_output_dir = coverage_output_dir
        self.coverage_include = coverage_include
        self.coverage_output_file = coverage_output_file

    def __str__(self):
        return '''Configuration
 - files_or_dirs: %s
 - verbosity: %s
 - tests: %s
 - port: %s
 - files_to_tests: %s
 - jobs: %s
 - split_jobs: %s

 - include_files: %s
 - include_tests: %s

 - exclude_files: %s
 - exclude_tests: %s

 - coverage_output_dir: %s
 - coverage_include_dir: %s
 - coverage_output_file: %s

 - django: %s
''' % (
        self.files_or_dirs,
        self.verbosity,
        self.tests,
        self.port,
        self.files_to_tests,
        self.jobs,
        self.split_jobs,

        self.include_files,
        self.include_tests,

        self.exclude_files,
        self.exclude_tests,

        self.coverage_output_dir,
        self.coverage_include,
        self.coverage_output_file,

        self.django,
    )


#=======================================================================================================================
# parse_cmdline
#=======================================================================================================================
def parse_cmdline(argv=None):
    """
    Parses command line and returns test directories, verbosity, test filter and test suites

    usage:
        runfiles.py  -v|--verbosity <level>  -t|--tests <Test.test1,Test2>  dirs|files

    Multiprocessing options:
    jobs=number (with the number of jobs to be used to run the tests)
    split_jobs='module'|'tests'
        if == module, a given job will always receive all the tests from a module
        if == tests, the tests will be split independently of their originating module (default)

    --exclude_files  = comma-separated list of patterns with files to exclude (fnmatch style)
    --include_files = comma-separated list of patterns with files to include (fnmatch style)
    --exclude_tests = comma-separated list of patterns with test names to exclude (fnmatch style)

    Note: if --tests is given, --exclude_files, --include_files and --exclude_tests are ignored!
    """
    if argv is None:
        argv = sys.argv

    verbosity = 2
    include_tests = None
    tests = None
    port = None
    jobs = 1
    split_jobs = 'tests'
    files_to_tests = {}
    coverage_output_dir = None
    coverage_include = None
    exclude_files = None
    exclude_tests = None
    include_files = None
    django = False

    from _pydev_getopt import gnu_getopt
    optlist, dirs = gnu_getopt(
        argv[1:], "",
        [
            "verbosity=",
            "tests=",

            "port=",
            "config_file=",

            "jobs=",
            "split_jobs=",

            "include_tests=",
            "include_files=",

            "exclude_files=",
            "exclude_tests=",

            "coverage_output_dir=",
            "coverage_include=",

            "django="
        ]
    )

    for opt, value in optlist:
        if opt in ("-v", "--verbosity"):
            verbosity = value

        elif opt in ("-p", "--port"):
            port = int(value)

        elif opt in ("-j", "--jobs"):
            jobs = int(value)

        elif opt in ("-s", "--split_jobs"):
            split_jobs = value
            if split_jobs not in ('module', 'tests'):
                raise AssertionError('Expected split to be either "module" or "tests". Was :%s' % (split_jobs,))

        elif opt in ("-d", "--coverage_output_dir",):
            coverage_output_dir = value.strip()

        elif opt in ("-i", "--coverage_include",):
            coverage_include = value.strip()

        elif opt in ("-I", "--include_tests"):
            include_tests = value.split(',')

        elif opt in ("-E", "--exclude_files"):
            exclude_files = value.split(',')

        elif opt in ("-F", "--include_files"):
            include_files = value.split(',')

        elif opt in ("-e", "--exclude_tests"):
            exclude_tests = value.split(',')

        elif opt in ("-t", "--tests"):
            tests = value.split(',')

        elif opt in ("--django",):
            django = value.strip() in ['true', 'True', '1']

        elif opt in ("-c", "--config_file"):
            config_file = value.strip()
            if os.path.exists(config_file):
                f = open(config_file, 'rU')
                try:
                    config_file_contents = f.read()
                finally:
                    f.close()

                if config_file_contents:
                    config_file_contents = config_file_contents.strip()

                if config_file_contents:
                    for line in config_file_contents.splitlines():
                        file_and_test = line.split('|')
                        if len(file_and_test) == 2:
                            file, test = file_and_test
                            if DictContains(files_to_tests, file):
                                files_to_tests[file].append(test)
                            else:
                                files_to_tests[file] = [test]

            else:
                sys.stderr.write('Could not find config file: %s\n' % (config_file,))

    if type([]) != type(dirs):
        dirs = [dirs]

    ret_dirs = []
    for d in dirs:
        if '|' in d:
            #paths may come from the ide separated by |
            ret_dirs.extend(d.split('|'))
        else:
            ret_dirs.append(d)

    verbosity = int(verbosity)

    if tests:
        if verbosity > 4:
            sys.stdout.write('--tests provided. Ignoring --exclude_files, --exclude_tests and --include_files\n')
        exclude_files = exclude_tests = include_files = None

    config = Configuration(
        ret_dirs,
        verbosity,
        include_tests,
        tests,
        port,
        files_to_tests,
        jobs,
        split_jobs,
        coverage_output_dir,
        coverage_include,
        exclude_files=exclude_files,
        exclude_tests=exclude_tests,
        include_files=include_files,
        django=django,
    )

    if verbosity > 5:
        sys.stdout.write(str(config) + '\n')
    return config


#=======================================================================================================================
# PydevTestRunner
#=======================================================================================================================
class PydevTestRunner(object):
    """ finds and runs a file or directory of files as a unit test """

    __py_extensions = ["*.py", "*.pyw"]
    __exclude_files = ["__init__.*"]

    #Just to check that only this attributes will be written to this file
    __slots__ = [
        'verbosity',  #Always used

        'files_to_tests',  #If this one is given, the ones below are not used

        'files_or_dirs',  #Files or directories received in the command line
        'include_tests',  #The filter used to collect the tests
        'tests',  #Strings with the tests to be run

        'jobs',  #Integer with the number of jobs that should be used to run the test cases
        'split_jobs',  #String with 'tests' or 'module' (how should the jobs be split)

        'configuration',
        'coverage',
    ]

    def __init__(self, configuration):
        self.verbosity = configuration.verbosity

        self.jobs = configuration.jobs
        self.split_jobs = configuration.split_jobs

        files_to_tests = configuration.files_to_tests
        if files_to_tests:
            self.files_to_tests = files_to_tests
            self.files_or_dirs = list(files_to_tests.keys())
            self.tests = None
        else:
            self.files_to_tests = {}
            self.files_or_dirs = configuration.files_or_dirs
            self.tests = configuration.tests

        self.configuration = configuration
        self.__adjust_path()


    def __adjust_path(self):
        """ add the current file or directory to the python path """
        path_to_append = None
        for n in xrange(len(self.files_or_dirs)):
            dir_name = self.__unixify(self.files_or_dirs[n])
            if os.path.isdir(dir_name):
                if not dir_name.endswith("/"):
                    self.files_or_dirs[n] = dir_name + "/"
                path_to_append = os.path.normpath(dir_name)
            elif os.path.isfile(dir_name):
                path_to_append = os.path.dirname(dir_name)
            else:
                if not os.path.exists(dir_name):
                    block_line = '*' * 120
                    sys.stderr.write('\n%s\n* PyDev test runner error: %s does not exist.\n%s\n' % (block_line, dir_name, block_line))
                    return
                msg = ("unknown type. \n%s\nshould be file or a directory.\n" % (dir_name))
                raise RuntimeError(msg)
        if path_to_append is not None:
            #Add it as the last one (so, first things are resolved against the default dirs and
            #if none resolves, then we try a relative import).
            sys.path.append(path_to_append)

    def __is_valid_py_file(self, fname):
        """ tests that a particular file contains the proper file extension
            and is not in the list of files to exclude """
        is_valid_fname = 0
        for invalid_fname in self.__class__.__exclude_files:
            is_valid_fname += int(not fnmatch.fnmatch(fname, invalid_fname))
        if_valid_ext = 0
        for ext in self.__class__.__py_extensions:
            if_valid_ext += int(fnmatch.fnmatch(fname, ext))
        return is_valid_fname > 0 and if_valid_ext > 0

    def __unixify(self, s):
        """ stupid windows. converts the backslash to forwardslash for consistency """
        return os.path.normpath(s).replace(os.sep, "/")

    def __importify(self, s, dir=False):
        """ turns directory separators into dots and removes the ".py*" extension
            so the string can be used as import statement """
        if not dir:
            dirname, fname = os.path.split(s)

            if fname.count('.') > 1:
                #if there's a file named xxx.xx.py, it is not a valid module, so, let's not load it...
                return

            imp_stmt_pieces = [dirname.replace("\\", "/").replace("/", "."), os.path.splitext(fname)[0]]

            if len(imp_stmt_pieces[0]) == 0:
                imp_stmt_pieces = imp_stmt_pieces[1:]

            return ".".join(imp_stmt_pieces)

        else:  #handle dir
            return s.replace("\\", "/").replace("/", ".")

    def __add_files(self, pyfiles, root, files):
        """ if files match, appends them to pyfiles. used by os.path.walk fcn """
        for fname in files:
            if self.__is_valid_py_file(fname):
                name_without_base_dir = self.__unixify(os.path.join(root, fname))
                pyfiles.append(name_without_base_dir)


    def find_import_files(self):
        """ return a list of files to import """
        if self.files_to_tests:
            pyfiles = self.files_to_tests.keys()
        else:
            pyfiles = []

            for base_dir in self.files_or_dirs:
                if os.path.isdir(base_dir):
                    if hasattr(os, 'walk'):
                        for root, dirs, files in os.walk(base_dir):

                            #Note: handling directories that should be excluded from the search because
                            #they don't have __init__.py
                            exclude = {}
                            for d in dirs:
                                for init in ['__init__.py', '__init__.pyo', '__init__.pyc', '__init__.pyw']:
                                    if os.path.exists(os.path.join(root, d, init).replace('\\', '/')):
                                        break
                                else:
                                    exclude[d] = 1

                            if exclude:
                                new = []
                                for d in dirs:
                                    if d not in exclude:
                                        new.append(d)

                                dirs[:] = new

                            self.__add_files(pyfiles, root, files)
                    else:
                        # jython2.1 is too old for os.walk!
                        os.path.walk(base_dir, self.__add_files, pyfiles)

                elif os.path.isfile(base_dir):
                    pyfiles.append(base_dir)

        if self.configuration.exclude_files or self.configuration.include_files:
            ret = []
            for f in pyfiles:
                add = True
                basename = os.path.basename(f)
                if self.configuration.include_files:
                    add = False

                    for pat in self.configuration.include_files:
                        if fnmatch.fnmatchcase(basename, pat):
                            add = True
                            break

                if not add:
                    if self.verbosity > 3:
                        sys.stdout.write('Skipped file: %s (did not match any include_files pattern: %s)\n' % (f, self.configuration.include_files))

                elif self.configuration.exclude_files:
                    for pat in self.configuration.exclude_files:
                        if fnmatch.fnmatchcase(basename, pat):
                            if self.verbosity > 3:
                                sys.stdout.write('Skipped file: %s (matched exclude_files pattern: %s)\n' % (f, pat))

                            elif self.verbosity > 2:
                                sys.stdout.write('Skipped file: %s\n' % (f,))

                            add = False
                            break

                if add:
                    if self.verbosity > 3:
                        sys.stdout.write('Adding file: %s for test discovery.\n' % (f,))
                    ret.append(f)

            pyfiles = ret


        return pyfiles

    def __get_module_from_str(self, modname, print_exception, pyfile):
        """ Import the module in the given import path.
            * Returns the "final" module, so importing "coilib40.subject.visu"
            returns the "visu" module, not the "coilib40" as returned by __import__ """
        try:
            mod = __import__(modname)
            for part in modname.split('.')[1:]:
                mod = getattr(mod, part)
            return mod
        except:
            if print_exception:
                import pydev_runfiles_xml_rpc
                import pydevd_io
                buf_err = pydevd_io.StartRedirect(keep_original_redirection=True, std='stderr')
                buf_out = pydevd_io.StartRedirect(keep_original_redirection=True, std='stdout')
                try:
                    import traceback;traceback.print_exc()
                    sys.stderr.write('ERROR: Module: %s could not be imported (file: %s).\n' % (modname, pyfile))
                finally:
                    pydevd_io.EndRedirect('stderr')
                    pydevd_io.EndRedirect('stdout')

                pydev_runfiles_xml_rpc.notifyTest(
                    'error', buf_out.getvalue(), buf_err.getvalue(), pyfile, modname, 0)

            return None

    def find_modules_from_files(self, pyfiles):
        """ returns a list of modules given a list of files """
        #let's make sure that the paths we want are in the pythonpath...
        imports = [(s, self.__importify(s)) for s in pyfiles]

        system_paths = []
        for s in sys.path:
            system_paths.append(self.__importify(s, True))


        ret = []
        for pyfile, imp in imports:
            if imp is None:
                continue  #can happen if a file is not a valid module
            choices = []
            for s in system_paths:
                if imp.startswith(s):
                    add = imp[len(s) + 1:]
                    if add:
                        choices.append(add)
                    #sys.stdout.write(' ' + add + ' ')

            if not choices:
                sys.stdout.write('PYTHONPATH not found for file: %s\n' % imp)
            else:
                for i, import_str in enumerate(choices):
                    print_exception = i == len(choices) - 1
                    mod = self.__get_module_from_str(import_str, print_exception, pyfile)
                    if mod is not None:
                        ret.append((pyfile, mod, import_str))
                        break


        return ret

    #===================================================================================================================
    # GetTestCaseNames
    #===================================================================================================================
    class GetTestCaseNames:
        """Yes, we need a class for that (cannot use outer context on jython 2.1)"""

        def __init__(self, accepted_classes, accepted_methods):
            self.accepted_classes = accepted_classes
            self.accepted_methods = accepted_methods

        def __call__(self, testCaseClass):
            """Return a sorted sequence of method names found within testCaseClass"""
            testFnNames = []
            className = testCaseClass.__name__

            if DictContains(self.accepted_classes, className):
                for attrname in dir(testCaseClass):
                    #If a class is chosen, we select all the 'test' methods'
                    if attrname.startswith('test') and hasattr(getattr(testCaseClass, attrname), '__call__'):
                        testFnNames.append(attrname)

            else:
                for attrname in dir(testCaseClass):
                    #If we have the class+method name, we must do a full check and have an exact match.
                    if DictContains(self.accepted_methods, className + '.' + attrname):
                        if hasattr(getattr(testCaseClass, attrname), '__call__'):
                            testFnNames.append(attrname)

            #sorted() is not available in jython 2.1
            testFnNames.sort()
            return testFnNames


    def _decorate_test_suite(self, suite, pyfile, module_name):
        import unittest
        if isinstance(suite, unittest.TestSuite):
            add = False
            suite.__pydev_pyfile__ = pyfile
            suite.__pydev_module_name__ = module_name

            for t in suite._tests:
                t.__pydev_pyfile__ = pyfile
                t.__pydev_module_name__ = module_name
                if self._decorate_test_suite(t, pyfile, module_name):
                    add = True

            return add

        elif isinstance(suite, unittest.TestCase):
            return True

        else:
            return False



    def find_tests_from_modules(self, file_and_modules_and_module_name):
        """ returns the unittests given a list of modules """
        #Use our own suite!
        import pydev_runfiles_unittest
        import unittest
        unittest.TestLoader.suiteClass = pydev_runfiles_unittest.PydevTestSuite
        loader = unittest.TestLoader()

        ret = []
        if self.files_to_tests:
            for pyfile, m, module_name in file_and_modules_and_module_name:
                accepted_classes = {}
                accepted_methods = {}
                tests = self.files_to_tests[pyfile]
                for t in tests:
                    accepted_methods[t] = t

                loader.getTestCaseNames = self.GetTestCaseNames(accepted_classes, accepted_methods)

                suite = loader.loadTestsFromModule(m)
                if self._decorate_test_suite(suite, pyfile, module_name):
                    ret.append(suite)
            return ret


        if self.tests:
            accepted_classes = {}
            accepted_methods = {}

            for t in self.tests:
                splitted = t.split('.')
                if len(splitted) == 1:
                    accepted_classes[t] = t

                elif len(splitted) == 2:
                    accepted_methods[t] = t

            loader.getTestCaseNames = self.GetTestCaseNames(accepted_classes, accepted_methods)


        for pyfile, m, module_name in file_and_modules_and_module_name:
            suite = loader.loadTestsFromModule(m)
            if self._decorate_test_suite(suite, pyfile, module_name):
                ret.append(suite)

        return ret


    def filter_tests(self, test_objs, internal_call=False):
        """ based on a filter name, only return those tests that have
            the test case names that match """
        import unittest
        if not internal_call:
            if not self.configuration.include_tests and not self.tests and not self.configuration.exclude_tests:
                #No need to filter if we have nothing to filter!
                return test_objs

            if self.verbosity > 1:
                if self.configuration.include_tests:
                    sys.stdout.write('Tests to include: %s\n' % (self.configuration.include_tests,))

                if self.tests:
                    sys.stdout.write('Tests to run: %s\n' % (self.tests,))

                if self.configuration.exclude_tests:
                    sys.stdout.write('Tests to exclude: %s\n' % (self.configuration.exclude_tests,))

        test_suite = []
        for test_obj in test_objs:

            if isinstance(test_obj, unittest.TestSuite):
                #Note: keep the suites as they are and just 'fix' the tests (so, don't use the iter_tests).
                if test_obj._tests:
                    test_obj._tests = self.filter_tests(test_obj._tests, True)
                    if test_obj._tests:  #Only add the suite if we still have tests there.
                        test_suite.append(test_obj)

            elif isinstance(test_obj, unittest.TestCase):
                try:
                    testMethodName = test_obj._TestCase__testMethodName
                except AttributeError:
                    #changed in python 2.5
                    testMethodName = test_obj._testMethodName

                add = True
                if self.configuration.exclude_tests:
                    for pat in self.configuration.exclude_tests:
                        if fnmatch.fnmatchcase(testMethodName, pat):
                            if self.verbosity > 3:
                                sys.stdout.write('Skipped test: %s (matched exclude_tests pattern: %s)\n' % (testMethodName, pat))

                            elif self.verbosity > 2:
                                sys.stdout.write('Skipped test: %s\n' % (testMethodName,))

                            add = False
                            break

                if add:
                    if self.__match_tests(self.tests, test_obj, testMethodName):
                        include = True
                        if self.configuration.include_tests:
                            include = False
                            for pat in self.configuration.include_tests:
                                if fnmatch.fnmatchcase(testMethodName, pat):
                                    include = True
                                    break
                        if include:
                            test_suite.append(test_obj)
                        else:
                            if self.verbosity > 3:
                                sys.stdout.write('Skipped test: %s (did not match any include_tests pattern %s)\n' % (self.configuration.include_tests,))
        return test_suite


    def iter_tests(self, test_objs):
        #Note: not using yield because of Jython 2.1.
        import unittest
        tests = []
        for test_obj in test_objs:
            if isinstance(test_obj, unittest.TestSuite):
                tests.extend(self.iter_tests(test_obj._tests))

            elif isinstance(test_obj, unittest.TestCase):
                tests.append(test_obj)
        return tests


    def list_test_names(self, test_objs):
        names = []
        for tc in self.iter_tests(test_objs):
            try:
                testMethodName = tc._TestCase__testMethodName
            except AttributeError:
                #changed in python 2.5
                testMethodName = tc._testMethodName
            names.append(testMethodName)
        return names


    def __match_tests(self, tests, test_case, test_method_name):
        if not tests:
            return 1

        for t in tests:
            class_and_method = t.split('.')
            if len(class_and_method) == 1:
                #only class name
                if class_and_method[0] == test_case.__class__.__name__:
                    return 1

            elif len(class_and_method) == 2:
                if class_and_method[0] == test_case.__class__.__name__ and class_and_method[1] == test_method_name:
                    return 1

        return 0


    def __match(self, filter_list, name):
        """ returns whether a test name matches the test filter """
        if filter_list is None:
            return 1
        for f in filter_list:
            if re.match(f, name):
                return 1
        return 0


    def run_tests(self, handle_coverage=True):
        """ runs all tests """
        sys.stdout.write("Finding files... ")
        files = self.find_import_files()
        if self.verbosity > 3:
            sys.stdout.write('%s ... done.\n' % (self.files_or_dirs))
        else:
            sys.stdout.write('done.\n')
        sys.stdout.write("Importing test modules ... ")


        if handle_coverage:
            coverage_files, coverage = StartCoverageSupport(self.configuration)

        file_and_modules_and_module_name = self.find_modules_from_files(files)
        sys.stdout.write("done.\n")

        all_tests = self.find_tests_from_modules(file_and_modules_and_module_name)
        all_tests = self.filter_tests(all_tests)

        import pydev_runfiles_unittest
        test_suite = pydev_runfiles_unittest.PydevTestSuite(all_tests)
        import pydev_runfiles_xml_rpc
        pydev_runfiles_xml_rpc.notifyTestsCollected(test_suite.countTestCases())

        start_time = time.time()

        def run_tests():
            executed_in_parallel = False
            if self.jobs > 1:
                import pydev_runfiles_parallel

                #What may happen is that the number of jobs needed is lower than the number of jobs requested
                #(e.g.: 2 jobs were requested for running 1 test) -- in which case ExecuteTestsInParallel will
                #return False and won't run any tests.
                executed_in_parallel = pydev_runfiles_parallel.ExecuteTestsInParallel(
                    all_tests, self.jobs, self.split_jobs, self.verbosity, coverage_files, self.configuration.coverage_include)

            if not executed_in_parallel:
                #If in coverage, we don't need to pass anything here (coverage is already enabled for this execution).
                runner = pydev_runfiles_unittest.PydevTextTestRunner(stream=sys.stdout, descriptions=1, verbosity=self.verbosity)
                sys.stdout.write('\n')
                runner.run(test_suite)

        if self.configuration.django:
            MyDjangoTestSuiteRunner(run_tests).run_tests([])
        else:
            run_tests()

        if handle_coverage:
            coverage.stop()
            coverage.save()

        total_time = 'Finished in: %.2f secs.' % (time.time() - start_time,)
        pydev_runfiles_xml_rpc.notifyTestRunFinished(total_time)


try:
    from django.test.simple import DjangoTestSuiteRunner
except:
    class DjangoTestSuiteRunner:
        def __init__(self):
            pass

        def run_tests(self, *args, **kwargs):
            raise AssertionError("Unable to run suite with DjangoTestSuiteRunner because it couldn't be imported.")

class MyDjangoTestSuiteRunner(DjangoTestSuiteRunner):

    def __init__(self, on_run_suite):
        DjangoTestSuiteRunner.__init__(self)
        self.on_run_suite = on_run_suite

    def build_suite(self, *args, **kwargs):
        pass

    def suite_result(self, *args, **kwargs):
        pass

    def run_suite(self, *args, **kwargs):
        self.on_run_suite()


#=======================================================================================================================
# main
#=======================================================================================================================
def main(configuration):
    PydevTestRunner(configuration).run_tests()
