import sys
import ast
import pathlib
from typing import Tuple

from IPython import embed
import nixio as nix
import importlib.util

from pyrelacs.util.logging import config_logging
log = config_logging()

from IPython import embed

class Repro:
    """
    Repro Class that searches in the repro folder for classes instances and executes the
    the run function in the searched class

    """

    def __init__(self) -> None:
        pass

    def run_repro(
        self, nix_file: nix.File, name: str, file: pathlib.Path, *args, **kwargs
    ) -> None:

        spec = importlib.util.spec_from_file_location("rep", file)
        if not spec:
            log.error("Could not load the file")
        else:
            module = importlib.util.module_from_spec(spec)
            if not module:
                log.error("Could not load the module of the repro")
            else:
                sys.modules[name] = module
                spec.loader.exec_module(module)
                if hasattr(module, name):
                    rep_class = getattr(module, name)
                    rep_class.run(nix_file)
                else:
                    raise AttributeError(f"{file.name} has no {name} class")

    def names_of_repros(self) -> Tuple[list, list]:
        """
        Searches for class names in the repro folder in all python files

        Returns
        -------
        Tuple[list, list]
            list of class names
            list of file names from the class names
        """

        file_path_cur = pathlib.Path(__file__).parent
        python_files = list(file_path_cur.glob("**/*.py"))
        exclude_files = ["repros.py", "__init__.py"]
        python_files = [f for f in python_files if f.name not in exclude_files]
        repro_names = []
        file_names = []
        for python_file in python_files:
            with open(python_file, "r") as file:
                file_content = file.read()
                tree = ast.parse(file_content)
                class_name = [
                    node.name
                    for node in ast.walk(tree)
                    if isinstance(node, ast.ClassDef)
                ]
                repro_names.extend(class_name)
                file_names.append(python_file)
            file.close()
        return repro_names, file_names
