# Path: lib/python/asterisk/test_runner.py
# def load_and_parse_module(type_name):
#     """Take a qualified module/object name, load the module, and return
#     a typename specifying the object
# 
#     Keyword Arguments:
#     type_name A fully qualified module/object to load into memory
# 
#     Returns:
#     An object type that to be instantiated
#     None on error
#     """
# 
#     LOGGER.debug("Importing %s" % type_name)
# 
#     # Split the object typename into its constituent parts - the module name
#     # and the actual type of the object in that module
#     parts = type_name.split('.')
#     module_name = ".".join(parts[:-1])
# 
#     if not len(module_name):
#         LOGGER.error("No module specified: %s" % typename)
#         return None
# 
#     if os.path.exists('lib/python/asterisk/%s.py' % module_name):
#         # This is convoluted but required.  lib/python/asterisk packages
#         # must be loaded using absolute package names and 'asterisk' must
#         # be included in the list of parts.  We cannot simply prepend
#         # type_name from the start because this blocks load of modules
#         # that are local to the test (add-test-to-search-path: 'True').
#         module_name = 'asterisk.' + module_name
#         parts = ['asterisk'] + parts
# 
#     module = __import__(module_name)
#     for comp in parts[1:]:
#         module = getattr(module, comp)
#     return module
# 
# Path: lib/python/asterisk/pluggable_registry.py
# PLUGGABLE_ACTION_REGISTRY = PluggableRegistry()
# 
# PLUGGABLE_EVENT_REGISTRY = PluggableRegistry()
# 
# class PluggableRegistry(object):
#     """Registry for pluggable modules"""
# 
#     def __init__(self):
#         self.registry = {}
# 
#     def register(self, key, factory):
#         """Register a module"""
#         self.registry[key] = factory
# 
#     def check(self, key):
#         """Check whether a module factory exists for the given key"""
#         if key in self.registry:
#             return True
#         return False
# 
#     def get_class(self, key):
#         """Get the class for a module"""
#         return self.registry[key]


import os
import sys
import logging
import shutil
import re
from .ami import AMIEventInstance
from twisted.internet import reactor
from starpy import fastagi
from .test_runner import load_and_parse_module
from .pluggable_registry import PLUGGABLE_ACTION_REGISTRY,\
    PLUGGABLE_EVENT_REGISTRY,\
    PluggableRegistry
from . import matcher
        Keyword Arguments:
        test_object The main test object
        config      The pluggable module config
        """
        self.test_object = test_object

    def run(self, triggered_by, source, extra):
        """Execute the action, which stops the test

        Keyword Arguments:
        triggered_by The event that triggered this action
        source       The Asterisk interface object that provided the event
        extra        Source dependent data
        """
        self.test_object.stop_reactor()
PLUGGABLE_ACTION_REGISTRY.register("stop_test", StopTestActionModule)


class PjsuaPhoneActionModule(object):
    """An action module that instructs a phone to perform an action."""

    def __init__(self, test_object, config):
        """Setup the test start observer"""
        self.test_object = test_object
        self.module = "phones"
        self.method = config["action"]
        self.config = config

    def run(self, triggered_by, source, extra):
        """Instruct phone to perform action"""

# Path: lib/python/asterisk/test_runner.py
# def load_and_parse_module(type_name):
#     """Take a qualified module/object name, load the module, and return
#     a typename specifying the object
# 
#     Keyword Arguments:
#     type_name A fully qualified module/object to load into memory
# 
#     Returns:
#     An object type that to be instantiated
#     None on error
#     """
# 
#     LOGGER.debug("Importing %s" % type_name)
# 
#     # Split the object typename into its constituent parts - the module name
#     # and the actual type of the object in that module
#     parts = type_name.split('.')
#     module_name = ".".join(parts[:-1])
# 
#     if not len(module_name):
#         LOGGER.error("No module specified: %s" % typename)
#         return None
# 
#     if os.path.exists('lib/python/asterisk/%s.py' % module_name):
#         # This is convoluted but required.  lib/python/asterisk packages
#         # must be loaded using absolute package names and 'asterisk' must
#         # be included in the list of parts.  We cannot simply prepend
#         # type_name from the start because this blocks load of modules
#         # that are local to the test (add-test-to-search-path: 'True').
#         module_name = 'asterisk.' + module_name
#         parts = ['asterisk'] + parts
# 
#     module = __import__(module_name)
#     for comp in parts[1:]:
#         module = getattr(module, comp)
#     return module
# 
# Path: lib/python/asterisk/pluggable_registry.py
# PLUGGABLE_ACTION_REGISTRY = PluggableRegistry()
# 
# PLUGGABLE_EVENT_REGISTRY = PluggableRegistry()
# 
# class PluggableRegistry(object):
#     """Registry for pluggable modules"""
# 
#     def __init__(self):
#         self.registry = {}
# 
#     def register(self, key, factory):
#         """Register a module"""
#         self.registry[key] = factory
# 
#     def check(self, key):
#         """Check whether a module factory exists for the given key"""
#         if key in self.registry:
#             return True
#         return False
# 
#     def get_class(self, key):
#         """Get the class for a module"""
#         return self.registry[key]


# Path: lib/python/asterisk/pluggable_modules.py
import os
import sys
import logging
import shutil
import re
from .ami import AMIEventInstance
from twisted.internet import reactor
from starpy import fastagi
from .test_runner import load_and_parse_module
from .pluggable_registry import PLUGGABLE_ACTION_REGISTRY,\
    PLUGGABLE_EVENT_REGISTRY,\
    PluggableRegistry
from . import matcher

        Keyword Arguments:
        test_object The main test object
        config      The pluggable module config
        """
        self.test_object = test_object

    def run(self, triggered_by, source, extra):
        """Execute the action, which stops the test

        Keyword Arguments:
        triggered_by The event that triggered this action
        source       The Asterisk interface object that provided the event
        extra        Source dependent data
        """
        self.test_object.stop_reactor()
PLUGGABLE_ACTION_REGISTRY.register("stop_test", StopTestActionModule)


class PjsuaPhoneActionModule(object):
    """An action module that instructs a phone to perform an action."""

    def __init__(self, test_object, config):
        """Setup the test start observer"""
        self.test_object = test_object
        self.module = "phones"
        self.method = config["action"]
        self.config = config

    def run(self, triggered_by, source, extra):
        """Instruct phone to perform action"""

        method = load_and_parse_module(self.module + "." + self.method)