import functools

from swarmauri_standard.tracing.SimpleTracer import SimpleTracer

# Initialize the global tracer object
tracer = SimpleTracer()


def CallableTracer(func):
    """
    A decorator to trace function or method calls, capturing inputs, outputs, and the caller.
    """

    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        # Trying to automatically identify the caller details; practical implementations
        # might need to adjust based on specific requirements or environment.
        caller_info = f"{func.__module__}.{func.__name__}"

        # Start a new trace context for this callable
        tracer.start_trace(
            name=caller_info, initial_attributes={"args": args, "kwargs": kwargs}
        )

        try:
            # Call the actual function/method
            result = func(*args, **kwargs)
            tracer.annotate_trace(key="result", value=result)
            return result
        except Exception as e:
            # Optionally annotate the trace with the exception details
            tracer.annotate_trace(key="exception", value=str(e))
            raise  # Re-raise the exception to not interfere with the program's flow
        finally:
            # End the trace after the function call is complete
            tracer.end_trace()

    return wrapper
