from typing import TypeVar, Any

T = TypeVar('T')


class ClassProxy:
    """
    类代理
    """
    def __init__(self, class_type: type[T], *args, **kwargs):
        """
        初始化代理
        
        Args:
            class_type: 要代理的类类型
            *args: 传递给类构造函数的位置参数
            **kwargs: 传递给类构造函数的关键字参数
        """
        # 使用 object.__setattr__ 避免触发 __setattr__ 方法
        object.__setattr__(self, '_instance', class_type(*args, **kwargs))
        object.__setattr__(self, '_class_type', class_type)

    def __getattr__(self, name: str) -> Any:
        """
        属性访问代理
        
        Args:
            name: 属性名
            
        Returns:
            从实际实例获取的属性值
        """
        return getattr(self._instance, name)

    def __setattr__(self, name: str, value: Any) -> None:
        """
        属性设置代理
        
        Args:
            name: 属性名
            value: 属性值
        """
        setattr(self._instance, name, value)
    
    def __call__(self, *args, **kwargs) -> Any:
        """
        如果被代理的实例是可调用的，则支持调用
        """
        return self._instance(*args, **kwargs)
    
    def __repr__(self) -> str:
        """返回代理的字符串表示"""
        return f"ClassProxy({self._class_type.__name__}) -> {repr(self._instance)}"
    
    def __str__(self) -> str:
        """返回实例的字符串表示"""
        return str(self._instance)
    
    @property
    def instance(self) -> T:
        """获取被代理的实际实例"""
        return self._instance
    
    @property
    def class_type(self) -> type[T]:
        """获取被代理的类类型"""
        return self._class_type
    
    def get_methods(self) -> list[str]:
        """
        获取类的所有公共方法名
        
        Returns:
            方法名列表
        """
        import inspect
        methods = []
        for name, method in inspect.getmembers(self._class_type, predicate=inspect.isfunction):
            if not name.startswith('_'):  # 排除私有方法
                methods.append(name)
        return methods
    
    def get_attributes(self) -> list[str]:
        """
        获取类的所有公共属性名
        
        Returns:
            属性名列表
        """
        import inspect
        attributes = []
        for name, _ in inspect.getmembers(self._class_type):
            if not name.startswith('_') and not callable(getattr(self._class_type, name, None)):
                attributes.append(name)
        return attributes

