# Path: bipy/pipeline/stages.py
# class AbstractStage(object):
#     """
#     Wrapper around a stage for use with the pipeline manager. Subclasses should
#     implement their own __init__ in addition to calling the super
#     __init__. __init__ should parse the appropriate information from the config
#     dict and save it in the objects state. __call__ should be implemented as a
#     pure function with no closures.
# 
#     """
# 
#     stage = "abstract"
# 
#     def __init__(self, config):
#         self.config = config
#         self._validate_config()
# 
#     def _start_message(self, in_file, **kwargs):
#         if kwargs:
#             logger.info("Starting %s on %s with arguments %s." % (self.stage,
#                                                                   in_file,
#                                                                   kwargs))
#         else:
#             logger.info("Starting %s on %s." % (self.stage, in_file))
# 
#     def _end_message(self, in_file):
#         logger.info("%s complete on %s." % (self.stage, in_file))
# 
#     def _check_run(self, in_file):
#         if not file_exists(in_file):
#             raise IOError("%s not found." % (in_file))
# 
#     def __call__(self, in_file):
#         pass
# 
#     def _validate_config(self):
#         if "stage" not in self.config:
#             raise ValueError('Could not find "stage" in the config file.')
# 
# Path: bipy/plugins.py
# class StageRepository(object):
#     """
#     builds a repository of all of the stage objects. loads all of the
#     AbstractStage objects in the toolbox directory and adds to it anything
#     in the plugins directory.
# 
#     will overwrite the main toolbox stages with the ones in the plugins
#     directory
# 
#     """
# 
#     def __init__(self, config):
#         self.config = config
#         self.plugins = {}
#         #self.scan(get_in(config, "dir", "plugins"))
#         plugin_dir = get_in(config, ("dir", "plugins"))
#         if plugin_dir:
#             logger.info("Scanning %s for plugins." % plugin_dir)
#             plugins = types.ModuleType("plugins")
#             plugins.__path__ = [plugin_dir]
#             sys.modules["plugins"] = plugins
#             self.scan(plugin_dir)
#         else:
#             self.scan()
# 
#     def scan(self, plugin_dir=None):
# 
#         files = os.listdir(PluginDirectory)
#         if plugin_dir:
#             sys.path.append(plugin_dir)
#             files += os.listdir(plugin_dir)
# 
#         plugins = []
#         for fn in files:
#             if fn.endswith('.py'):
#                 plugins.append(fn)
#         mods = [fn.split('.')[0] for fn in plugins]
#         # build the map of plugins
#         for modname in mods:
#             try:
#                 mod = import_(modname, PackagePrefix)
#             except:
#                 logger.error("Error loading plugin: %s" % modname)
#                 traceback.print_exc()
#                 continue
#             self.scan_module(mod)
# 
#     def scan_module(self, mod):
#         ns = dir(mod)
#         for name in ns:
#             # skip over the base class
#             thing = getattr(mod, name)
#             if thing == AbstractStage:
#                 continue
#             if type(thing) is not type:
#                 continue
#             if issubclass(thing, AbstractStage):
#                 # found a plugin!
#                 self.plugins[thing.stage] = thing
# 
#     def __getitem__(self, key):
#         return self.plugins.get(key, None)


import yaml
import unittest
import os
import tempfile
from bipy.pipeline.stages import AbstractStage
from bipy.plugins import StageRepository
from bcbio.utils import safe_makedir

STAGENAME = "plugins"


class TestPlugins(unittest.TestCase):

    def setUp(self):
        self.config_file = os.path.join("test", STAGENAME,
                                        "test_" + STAGENAME + ".yaml")
        with open(self.config_file) as in_handle:
            self.config = yaml.load(in_handle)
        self.repository = StageRepository(self.config)
        self.out_dir = os.path.join(self.config["dir"]["results"], "test",
                                    STAGENAME)
        safe_makedir(self.out_dir)

    def test_repository(self):
        """
        test that the repository object gets made

        """
        repository = StageRepository(self.config)
        self.assertTrue(isinstance(repository, StageRepository))

    def test_builtin_plugins(self):
        """
        test that we can find some of the built in plugins

        """
        fastqc = self.repository["fastqc"]

# Path: bipy/pipeline/stages.py
# class AbstractStage(object):
#     """
#     Wrapper around a stage for use with the pipeline manager. Subclasses should
#     implement their own __init__ in addition to calling the super
#     __init__. __init__ should parse the appropriate information from the config
#     dict and save it in the objects state. __call__ should be implemented as a
#     pure function with no closures.
# 
#     """
# 
#     stage = "abstract"
# 
#     def __init__(self, config):
#         self.config = config
#         self._validate_config()
# 
#     def _start_message(self, in_file, **kwargs):
#         if kwargs:
#             logger.info("Starting %s on %s with arguments %s." % (self.stage,
#                                                                   in_file,
#                                                                   kwargs))
#         else:
#             logger.info("Starting %s on %s." % (self.stage, in_file))
# 
#     def _end_message(self, in_file):
#         logger.info("%s complete on %s." % (self.stage, in_file))
# 
#     def _check_run(self, in_file):
#         if not file_exists(in_file):
#             raise IOError("%s not found." % (in_file))
# 
#     def __call__(self, in_file):
#         pass
# 
#     def _validate_config(self):
#         if "stage" not in self.config:
#             raise ValueError('Could not find "stage" in the config file.')
# 
# Path: bipy/plugins.py
# class StageRepository(object):
#     """
#     builds a repository of all of the stage objects. loads all of the
#     AbstractStage objects in the toolbox directory and adds to it anything
#     in the plugins directory.
# 
#     will overwrite the main toolbox stages with the ones in the plugins
#     directory
# 
#     """
# 
#     def __init__(self, config):
#         self.config = config
#         self.plugins = {}
#         #self.scan(get_in(config, "dir", "plugins"))
#         plugin_dir = get_in(config, ("dir", "plugins"))
#         if plugin_dir:
#             logger.info("Scanning %s for plugins." % plugin_dir)
#             plugins = types.ModuleType("plugins")
#             plugins.__path__ = [plugin_dir]
#             sys.modules["plugins"] = plugins
#             self.scan(plugin_dir)
#         else:
#             self.scan()
# 
#     def scan(self, plugin_dir=None):
# 
#         files = os.listdir(PluginDirectory)
#         if plugin_dir:
#             sys.path.append(plugin_dir)
#             files += os.listdir(plugin_dir)
# 
#         plugins = []
#         for fn in files:
#             if fn.endswith('.py'):
#                 plugins.append(fn)
#         mods = [fn.split('.')[0] for fn in plugins]
#         # build the map of plugins
#         for modname in mods:
#             try:
#                 mod = import_(modname, PackagePrefix)
#             except:
#                 logger.error("Error loading plugin: %s" % modname)
#                 traceback.print_exc()
#                 continue
#             self.scan_module(mod)
# 
#     def scan_module(self, mod):
#         ns = dir(mod)
#         for name in ns:
#             # skip over the base class
#             thing = getattr(mod, name)
#             if thing == AbstractStage:
#                 continue
#             if type(thing) is not type:
#                 continue
#             if issubclass(thing, AbstractStage):
#                 # found a plugin!
#                 self.plugins[thing.stage] = thing
# 
#     def __getitem__(self, key):
#         return self.plugins.get(key, None)


# Path: test/plugins/test_plugins.py
import yaml
import unittest
import os
import tempfile
from bipy.pipeline.stages import AbstractStage
from bipy.plugins import StageRepository
from bcbio.utils import safe_makedir


STAGENAME = "plugins"


class TestPlugins(unittest.TestCase):

    def setUp(self):
        self.config_file = os.path.join("test", STAGENAME,
                                        "test_" + STAGENAME + ".yaml")
        with open(self.config_file) as in_handle:
            self.config = yaml.load(in_handle)
        self.repository = StageRepository(self.config)
        self.out_dir = os.path.join(self.config["dir"]["results"], "test",
                                    STAGENAME)
        safe_makedir(self.out_dir)

    def test_repository(self):
        """
        test that the repository object gets made

        """
        repository = StageRepository(self.config)
        self.assertTrue(isinstance(repository, StageRepository))

    def test_builtin_plugins(self):
        """
        test that we can find some of the built in plugins

        """
        fastqc = self.repository["fastqc"]

        self.assertTrue(issubclass(fastqc, AbstractStage))