from functools import wraps
from typing import Callable, Any
from analogai.foundation.common.logging.app_logger import app_logger

_visited_set = set()

def get_visited_set() -> set:
    return _visited_set

def reset_visited_set():
    _visited_set.clear()

def clear_visited_set():
    _visited_set.clear()

def prevent_cycle(identifier_attr: str = "id", default_return: Any = None, check_before: bool = False):
    def decorator(func: Callable) -> Callable:
        @wraps(func)
        def wrapper(self):
            visited = get_visited_set()
            identifier = getattr(self, identifier_attr)
            
            if check_before and identifier in visited:
                app_logger.debug(f"Cycle detected at {identifier} - returning default value")
                return default_return
            
            visited.add(identifier)
            try:
                return func(self)
            finally:
                visited.discard(identifier)
        
        return wrapper
    return decorator