import importlib
import os
import glob
import inspect
import sys
import types
import transforms
from transforms.base import Transform, TransformError
import malcat


def get_transforms(data_dir, user_data_dir, reload_plugins=False):
    transforms = []
    seen = set()
    if user_data_dir and user_data_dir != data_dir:
        toscan = (user_data_dir, data_dir)
    else:
        toscan = (data_dir,)
    for plugins_path in toscan:
        for fname in glob.glob(os.path.join(plugins_path, "transforms", "*.py")):
            module_name = os.path.relpath(fname, plugins_path)[:-3].replace(os.sep, ".")
            if module_name in sys.modules:
                mod = sys.modules[module_name]
                if reload_plugins:
                    for element in dir(mod):
                        if isinstance(element, types.ModuleType):
                            importlib.reload(element)
                    mod = importlib.reload(mod)
            else:
                mod = importlib.import_module(module_name)
            for elemname in dir(mod):
                elem = getattr(mod, elemname)
                try:
                    if issubclass(elem, Transform) and elem != Transform and not elem in transforms:
                        if not elemname in seen:
                            transforms.append(elem)
                            seen.add(elemname)
                except TypeError: pass
    return sorted(transforms, key=lambda x:(x.category, x.name))


def get_transform_infos(transform_class):
    return transform_class.get_infos()
    

def transform(transform_class, data, args=[]):
    return bytes(transform_class()(data, *args))
