# Path: dftimewolf/lib/module.py
# T = TypeVar("T", bound="interface.AttributeContainer")  # pylint: disable=invalid-name,line-too-long
# class BaseModule(object):
# class PreflightModule(BaseModule):
# class ThreadAwareModule(BaseModule):
#   def __init__(self,
#                state: "state.DFTimewolfState",
#                name:Optional[str]=None,
#                critical: Optional[bool]=False):
#   def SetupLogging(self, threaded: bool = False) -> None:
#   def CleanUp(self) -> None:
#   def ModuleError(self, message: str, critical: bool=False) -> None:
#   def Process(self) -> None:
#   def SetUp(self, *args, **kwargs) -> None:  # type: ignore[no-untyped-def]
#   def Process(self) -> None:
#   def SetUp(self, *args, **kwargs) -> None:  # type: ignore[no-untyped-def]
#   def CleanUp(self) -> None:
#   def __init__(self,
#                state: "state.DFTimewolfState",
#                name: Optional[str]=None,
#                critical: Optional[bool]=False) -> None:
#   def PreProcess(self) -> None:
#   def Process(self, container: interface.AttributeContainer) -> None:
#   def PostProcess(self) -> None:
#   def GetThreadOnContainerType() -> Type[interface.AttributeContainer]:
#   def GetThreadPoolSize(self) -> int:
#   def KeepThreadedContainersInState() -> bool:
# 
# Path: dftimewolf/lib/modules/manager.py
# class ModulesManager(object):
#   ALLOW_MODULE_OVERRIDE = False
#   def DeregisterModule(cls, module_class: Type['module.BaseModule']) -> None:
#   def GetModuleByName(cls, name: str) -> Type['module.BaseModule']:
#   def RegisterModule(cls, module_class: Type['module.BaseModule']) -> None:
#   def RegisterModules(
#       cls, module_classes: List[Type['module.BaseModule']]) -> None:


import unittest
from dftimewolf.lib import module
from dftimewolf.lib.modules import manager

class ModulesManagerTest(unittest.TestCase):
  """Tests for the modules manager."""

  # pylint: disable=protected-access

  def setUp(self):
    manager.ModulesManager.ALLOW_MODULE_OVERRIDE = False

  def testModuleRegistration(self):
    """Tests the RegisterModule and DeregisterModule functions."""
    number_of_module_classes = len(manager.ModulesManager._module_classes)

    manager.ModulesManager.RegisterModule(TestModule)
    self.assertEqual(
        len(manager.ModulesManager._module_classes),
        number_of_module_classes + 1)

    with self.assertRaises(KeyError):
      manager.ModulesManager.RegisterModule(TestModule)

    manager.ModulesManager.DeregisterModule(TestModule)
    self.assertEqual(
        len(manager.ModulesManager._module_classes), number_of_module_classes)

  def testOverrideModuleRegistration(self):
    """Tests the RegisterModule with override functionality."""
    manager.ModulesManager.ALLOW_MODULE_OVERRIDE = True
    number_of_module_classes = len(manager.ModulesManager._module_classes)


# Path: dftimewolf/lib/module.py
# T = TypeVar("T", bound="interface.AttributeContainer")  # pylint: disable=invalid-name,line-too-long
# class BaseModule(object):
# class PreflightModule(BaseModule):
# class ThreadAwareModule(BaseModule):
#   def __init__(self,
#                state: "state.DFTimewolfState",
#                name:Optional[str]=None,
#                critical: Optional[bool]=False):
#   def SetupLogging(self, threaded: bool = False) -> None:
#   def CleanUp(self) -> None:
#   def ModuleError(self, message: str, critical: bool=False) -> None:
#   def Process(self) -> None:
#   def SetUp(self, *args, **kwargs) -> None:  # type: ignore[no-untyped-def]
#   def Process(self) -> None:
#   def SetUp(self, *args, **kwargs) -> None:  # type: ignore[no-untyped-def]
#   def CleanUp(self) -> None:
#   def __init__(self,
#                state: "state.DFTimewolfState",
#                name: Optional[str]=None,
#                critical: Optional[bool]=False) -> None:
#   def PreProcess(self) -> None:
#   def Process(self, container: interface.AttributeContainer) -> None:
#   def PostProcess(self) -> None:
#   def GetThreadOnContainerType() -> Type[interface.AttributeContainer]:
#   def GetThreadPoolSize(self) -> int:
#   def KeepThreadedContainersInState() -> bool:
# 
# Path: dftimewolf/lib/modules/manager.py
# class ModulesManager(object):
#   ALLOW_MODULE_OVERRIDE = False
#   def DeregisterModule(cls, module_class: Type['module.BaseModule']) -> None:
#   def GetModuleByName(cls, name: str) -> Type['module.BaseModule']:
#   def RegisterModule(cls, module_class: Type['module.BaseModule']) -> None:
#   def RegisterModules(
#       cls, module_classes: List[Type['module.BaseModule']]) -> None:


# Path: tests/lib/modules/manager.py
import unittest
from dftimewolf.lib import module
from dftimewolf.lib.modules import manager


class ModulesManagerTest(unittest.TestCase):
  """Tests for the modules manager."""

  # pylint: disable=protected-access

  def setUp(self):
    manager.ModulesManager.ALLOW_MODULE_OVERRIDE = False

  def testModuleRegistration(self):
    """Tests the RegisterModule and DeregisterModule functions."""
    number_of_module_classes = len(manager.ModulesManager._module_classes)

    manager.ModulesManager.RegisterModule(TestModule)
    self.assertEqual(
        len(manager.ModulesManager._module_classes),
        number_of_module_classes + 1)

    with self.assertRaises(KeyError):
      manager.ModulesManager.RegisterModule(TestModule)

    manager.ModulesManager.DeregisterModule(TestModule)
    self.assertEqual(
        len(manager.ModulesManager._module_classes), number_of_module_classes)

  def testOverrideModuleRegistration(self):
    """Tests the RegisterModule with override functionality."""
    manager.ModulesManager.ALLOW_MODULE_OVERRIDE = True
    number_of_module_classes = len(manager.ModulesManager._module_classes)


    manager.ModulesManager.RegisterModule(TestModule)