import sys
from io import StringIO
from typing import Dict
import subprocess

# Create a persistent namespace that will be shared across all executions
_persistent_namespace = {}

def run_python_repl(command: str) -> str:
    """
    Executes the provided Python command in a persistent environment and returns the output.
    Variables defined in one execution will be available in subsequent executions.
    """
    def execute_in_repl(command: str) -> str:
        """Helper function to execute the command in the persistent environment."""
        old_stdout = sys.stdout
        sys.stdout = mystdout = StringIO()
        
        # Use the persistent namespace
        global _persistent_namespace
        
        try:
            # Execute the command in the persistent namespace
            exec(command, _persistent_namespace)
            output = mystdout.getvalue()
        except Exception as e:
            output = f"Error: {str(e)}"
        finally:
            sys.stdout = old_stdout
        return output

    command = command.strip("```").strip()
    return execute_in_repl(command)


def read_function_source_code(function_name: str) -> str:
    """
    Read the source code of a function from any module path.
    
    Parameters:
        function_name (str): Fully qualified function name (e.g., 'bioagentos.tool.support_tools.write_python_code')
    
    Returns:
        str: The source code of the function
    """
    import inspect
    import importlib
    
    # Split the function name into module path and function name
    parts = function_name.split('.')
    module_path = '.'.join(parts[:-1])
    func_name = parts[-1]
    
    try:
        # Import the module
        module = importlib.import_module(module_path)
        
        # Get the function object from the module
        function = getattr(module, func_name)
        
        # Get the source code of the function
        source_code = inspect.getsource(function)
        
        return source_code
    except (ImportError, AttributeError) as e:
        return f"Error: Could not find function '{function_name}'. Details: {str(e)}"

# def request_human_feedback(question, context, reason_for_uncertainty):
#     """
#     Request human feedback on a question.

#     Parameters:
#         question (str): The question that needs human feedback.
#         context (str): Context or details that help the human understand the situation.
#         reason_for_uncertainty (str): Explanation for why the LLM is uncertain about its answer.

#     Returns:
#         str: The feedback provided by the human.
#     """
#     print("Requesting human feedback...")
#     print(f"Question: {question}")
#     print(f"Context: {context}")
#     print(f"Reason for Uncertainty: {reason_for_uncertainty}")
    
#     # Capture human feedback
#     human_response = input("Please provide your feedback: ")
    
#     return human_response
