#
# Copyright (C) 2016 Intel Corporation
#
# SPDX-License-Identifier: MIT
#

import os
import re
import sys
import unittest
import inspect

from oeqa.core.utils.path import findFile
from oeqa.core.utils.test import getSuiteModules, getCaseID

from oeqa.core.exception import OEQATestNotFound
from oeqa.core.case import OETestCase
from oeqa.core.decorator import decoratorClasses, OETestDecorator, \
        OETestDiscover

# When loading tests, the unittest framework stores any exceptions and
# displays them only when the run method is called.
#
# For our purposes, it is better to raise the exceptions in the loading
# step rather than waiting to run the test suite.
#
# Generate the function definition because this differ across python versions
# Python >= 3.4.4 uses tree parameters instead four but for example Python 3.5.3
# ueses four parameters so isn't incremental.
_failed_test_args = inspect.getfullargspec(unittest.loader._make_failed_test).args
exec("""def _make_failed_test(%s): raise exception""" % ', '.join(_failed_test_args))
unittest.loader._make_failed_test = _make_failed_test

def _find_duplicated_modules(suite, directory):
    for module in getSuiteModules(suite):
        path = findFile('%s.py' % module, directory)
        if path:
            raise ImportError("Duplicated %s module found in %s" % (module, path))

def _built_modules_dict(modules):
    modules_dict = {}

    if modules == None:
        return modules_dict

    for module in modules:
        # Assumption: package and module names do not contain upper case
        # characters, whereas class names do
        m = re.match(r'^([0-9a-z_.]+)(?:\.(\w[^.]*)(?:\.([^.]+))?)?$', module, flags=re.ASCII)
        if not m:
            continue

        module_name, class_name, test_name = m.groups()

        if module_name and module_name not in modules_dict:
            modules_dict[module_name] = {}
        if class_name and class_name not in modules_dict[module_name]:
            modules_dict[module_name][class_name] = []
        if test_name and test_name not in modules_dict[module_name][class_name]:
            modules_dict[module_name][class_name].append(test_name)

    return modules_dict

class OETestLoader(unittest.TestLoader):
    caseClass = OETestCase

    kwargs_names = ['testMethodPrefix', 'sortTestMethodUsing', 'suiteClass',
            '_top_level_dir']

    def __init__(self, tc, module_paths, modules, tests, modules_required,
            *args, **kwargs):
        self.tc = tc

        self.modules = _built_modules_dict(modules)

        self.tests = tests
        self.modules_required = modules_required

        self.tags_filter = kwargs.get("tags_filter", None)

        if isinstance(module_paths, str):
            module_paths = [module_paths]
        elif not isinstance(module_paths, list):
            raise TypeError('module_paths must be a str or a list of str')
        self.module_paths = module_paths

        for kwname in self.kwargs_names:
            if kwname in kwargs:
                setattr(self, kwname, kwargs[kwname])

        self._patchCaseClass(self.caseClass)

        super(OETestLoader, self).__init__()

    def _patchCaseClass(self, testCaseClass):
        # Adds custom attributes to the OETestCase class
        setattr(testCaseClass, 'tc', self.tc)
        setattr(testCaseClass, 'td', self.tc.td)
        setattr(testCaseClass, 'logger', self.tc.logger)

    def _registerTestCase(self, case):
        case_id = case.id()
        self.tc._registry['cases'][case_id] = case

    def _handleTestCaseDecorators(self, case):
        def _handle(obj):
            if isinstance(obj, OETestDecorator):
                if not obj.__class__ in decoratorClasses:
                    raise Exception("Decorator %s isn't registered" \
                            " in decoratorClasses." % obj.__name__)
                obj.bind(self.tc._registry, case)

        def _walk_closure(obj):
            if hasattr(obj, '__closure__') and obj.__closure__:
                for f in obj.__closure__:
                    obj = f.cell_contents
                    _handle(obj)
                    _walk_closure(obj)
        method = getattr(case, case._testMethodName, None)
        _walk_closure(method)

    def _filterTest(self, case):
        """
            Returns True if test case must be filtered, False otherwise.
        """
        # XXX; If the module has more than one namespace only use
        # the first to support run the whole module specifying the
        # <module_name>.[test_class].[test_name]
        module_name_small = case.__module__.split('.')[0]
        module_name = case.__module__

        class_name = case.__class__.__name__
        test_name = case._testMethodName

        # 'auto' is a reserved key word to run test cases automatically
        # warn users if their test case belong to a module named 'auto'
        if module_name_small == "auto":
            bb.warn("'auto' is a reserved key word for TEST_SUITES. "
                    "But test case '%s' is detected to belong to auto module. "
                    "Please condier using a new name for your module." % str(case))

        # check if case belongs to any specified module
        # if 'auto' is specified, such check is skipped
        if self.modules and not 'auto' in self.modules:
            module = None
            try:
                module = self.modules[module_name_small]
            except KeyError:
                try:
                    module = self.modules[module_name]
                except KeyError:
                    return True

            if module:
                if not class_name in module:
                    return True

                if module[class_name]:
                    if test_name not in module[class_name]:
                        return True

        # Decorator filters
        if self.tags_filter is not None and callable(self.tags_filter):
            alltags = set()
            # pull tags from the case class
            if hasattr(case, "__oeqa_testtags"):
                for t in getattr(case, "__oeqa_testtags"):
                    alltags.add(t)
            # pull tags from the method itself
            if hasattr(case, test_name):
                method = getattr(case, test_name)
                if hasattr(method, "__oeqa_testtags"):
                    for t in getattr(method, "__oeqa_testtags"):
                        alltags.add(t)

            if self.tags_filter(alltags):
                return True

        return False

    def _getTestCase(self, testCaseClass, tcName):
        if not hasattr(testCaseClass, '__oeqa_loader') and \
                issubclass(testCaseClass, OETestCase):
            # In order to support data_vars validation
            # monkey patch the default setUp/tearDown{Class} to use
            # the ones provided by OETestCase
            setattr(testCaseClass, 'setUpClassMethod',
                    getattr(testCaseClass, 'setUpClass'))
            setattr(testCaseClass, 'tearDownClassMethod',
                    getattr(testCaseClass, 'tearDownClass'))
            setattr(testCaseClass, 'setUpClass',
                    testCaseClass._oeSetUpClass)
            setattr(testCaseClass, 'tearDownClass',
                    testCaseClass._oeTearDownClass)

            # In order to support decorators initialization
            # monkey patch the default setUp/tearDown to use
            # a setUpDecorators/tearDownDecorators that methods
            # will call setUp/tearDown original methods.
            setattr(testCaseClass, 'setUpMethod',
                    getattr(testCaseClass, 'setUp')) 
            setattr(testCaseClass, 'tearDownMethod',
                    getattr(testCaseClass, 'tearDown'))
            setattr(testCaseClass, 'setUp', testCaseClass._oeSetUp)
            setattr(testCaseClass, 'tearDown', testCaseClass._oeTearDown)

            setattr(testCaseClass, '__oeqa_loader', True)

        case = testCaseClass(tcName)
        if isinstance(case, OETestCase):
            setattr(case, 'decorators', [])

        return case

    def loadTestsFromTestCase(self, testCaseClass):
        """
            Returns a suite of all tests cases contained in testCaseClass.
        """
        if issubclass(testCaseClass, unittest.suite.TestSuite):
            raise TypeError("Test cases should not be derived from TestSuite." \
                                " Maybe you meant to derive %s from TestCase?" \
                                % testCaseClass.__name__)
        if not issubclass(testCaseClass, unittest.case.TestCase):
            raise TypeError("Test %s is not derived from %s" % \
                    (testCaseClass.__name__, unittest.case.TestCase.__name__))

        testCaseNames = self.getTestCaseNames(testCaseClass)
        if not testCaseNames and hasattr(testCaseClass, 'runTest'):
            testCaseNames = ['runTest']

        suite = []
        for tcName in testCaseNames:
            case = self._getTestCase(testCaseClass, tcName)
            # Filer by case id
            if not (self.tests and not 'auto' in self.tests
                    and not getCaseID(case) in self.tests):
                self._handleTestCaseDecorators(case)

                # Filter by decorators
                if not self._filterTest(case):
                    self._registerTestCase(case)
                    suite.append(case)

        return self.suiteClass(suite)

    def _required_modules_validation(self):
        """
            Search in Test context registry if a required
            test is found, raise an exception when not found.
        """

        for module in self.modules_required:
            found = False

            # The module name is splitted to only compare the
            # first part of a test case id.
            comp_len = len(module.split('.'))
            for case in self.tc._registry['cases']:
                case_comp = '.'.join(case.split('.')[0:comp_len])
                if module == case_comp:
                    found = True
                    break

            if not found:
                raise OEQATestNotFound("Not found %s in loaded test cases" % \
                        module)

    def discover(self):
        big_suite = self.suiteClass()
        for path in self.module_paths:
            _find_duplicated_modules(big_suite, path)
            suite = super(OETestLoader, self).discover(path,
                    pattern='*.py', top_level_dir=path)
            big_suite.addTests(suite)

        cases = None
        discover_classes = [clss for clss in decoratorClasses
                            if issubclass(clss, OETestDiscover)]
        for clss in discover_classes:
            cases = clss.discover(self.tc._registry)

        if self.modules_required:
            self._required_modules_validation()

        return self.suiteClass(cases) if cases else big_suite

    def _filterModule(self, module):
        if module.__name__ in sys.builtin_module_names:
            msg = 'Tried to import %s test module but is a built-in'
            raise ImportError(msg % module.__name__)

        # XXX; If the module has more than one namespace only use
        # the first to support run the whole module specifying the
        # <module_name>.[test_class].[test_name]
        module_name_small = module.__name__.split('.')[0]
        module_name = module.__name__

        # Normal test modules are loaded if no modules were specified,
        # if module is in the specified module list or if 'auto' is in
        # module list.
        # Underscore modules are loaded only if specified in module list.
        load_module = True if not module_name.startswith('_') \
                              and (not self.modules \
                                   or module_name in self.modules \
                                   or module_name_small in self.modules \
                                   or 'auto' in self.modules) \
                           else False

        load_underscore = True if module_name.startswith('_') \
                                  and (module_name in self.modules or \
                                  module_name_small in self.modules) \
                               else False

        return (load_module, load_underscore)


    # XXX After Python 3.5, remove backward compatibility hacks for
    # use_load_tests deprecation via *args and **kws.  See issue 16662.
    if sys.version_info >= (3,5):
        def loadTestsFromModule(self, module, *args, pattern=None, **kws):
            """
                Returns a suite of all tests cases contained in module.
            """
            load_module, load_underscore = self._filterModule(module)

            if load_module or load_underscore:
                return super(OETestLoader, self).loadTestsFromModule(
                        module, *args, pattern=pattern, **kws)
            else:
                return self.suiteClass()
    else:
        def loadTestsFromModule(self, module, use_load_tests=True):
            """
                Returns a suite of all tests cases contained in module.
            """
            load_module, load_underscore = self._filterModule(module)

            if load_module or load_underscore:
                return super(OETestLoader, self).loadTestsFromModule(
                        module, use_load_tests)
            else:
                return self.suiteClass()
