import sys
import marshal
import imp
from test import test_support
from importlib import _w_long


def log_call(method):
    """Log method calls to self.log."""
    def log_and_call(self, *args, **kwargs):
        self.log.append(method.__name__)
        return method(self, *args, **kwargs)
    return log_and_call


class MockModule(object):
    
    """A mock module."""
    
    def __init__(self, name=None, file_path=None, pkg_list=None, __all__=None):
        if name is not None:
            self.__name__ = name
        if file_path is not None:
            self.__file__ = file_path
        if pkg_list is not None:
            self.__path__ = pkg_list
        if __all__ is not None:
            self.__all__ = __all__


# Mock Importers (with optional path_hooks support).

class ErrorImporter(object):

    """Mock importer to have a guaranteed error point."""

    def find_module(self, fullname, path=None):
        self.find_request = fullname, path
        raise ImportError

    @classmethod
    def set_on_sys_path(cls):
        error_entry = '<error>'
        sys.path.append(error_entry)
        ins = cls()
        sys.path_importer_cache[error_entry] = ins
        return ins


class PassImporter(object):

    """Mock importer that always pass on importing a module."""
    
    def __call__(self, path_entry):
        """Always pass when asked to create an importer."""
        raise ImportError

    def find_module(self, fullname, path=None):
        self.find_request = fullname, path
        return None

    @classmethod
    def set_on_sys_path(cls):
        pass_entry = '<pass>'
        sys.path.append(pass_entry)
        ins = cls()
        sys.path_importer_cache[pass_entry] = ins
        return ins


class SucceedImporter(object):

    """Mock importer that always succeed by returning 'self'."""
    
    def __init__(self):
        self.path_entries = []
        self.loaded_modules = []

    def __call__(self, path_entry):
        self.path_entries.append(path_entry)
        return self

    def find_module(self, fullname, path=None):
        self.find_request = fullname, path
        return self

    def load_module(self, fullname):
        self.load_request = fullname
        module = MockModule(fullname, '<succeed importer>')
        self.loaded_modules.append(module)
        sys.modules[fullname] = module
        return module

    @classmethod
    def set_on_sys_path(cls):
        succeed_entry = '<success>'
        sys.path.append(succeed_entry)
        ins = cls()
        sys.path_importer_cache[succeed_entry] = ins
        return ins
