# 导入Python标准库中的logging模块，用于实现插件运行过程中的日志记录功能
# 日志可以帮助开发者追踪插件的运行状态、排查错误等
import logging

# 创建一个日志记录器实例，其名称与当前模块(__name__)绑定
# 这样可以确保日志信息能够准确关联到插件模块，便于日志的分类和筛选
logger = logging.getLogger(__name__)


class BasePlugin:
    """
    插件系统的基类（抽象基类角色），所有自定义插件都必须继承此类
    
    该类的核心作用是：
    1. 定义插件必须包含的元数据规范（名称、描述、版本）
    2. 提供插件初始化和钩子注册的统一流程
    3. 封装获取插件信息的通用方法
    子类通过继承此类并实现特定方法，即可快速接入插件系统
    """
    
    # 插件元数据字段（子类必须显式赋值，否则初始化会失败）
    PLUGIN_NAME = None  # 插件的唯一标识名称，用于在系统中区分不同插件，例如"DataCleanPlugin"
    PLUGIN_DESCRIPTION = None  # 插件功能的详细描述，说明插件的作用和使用场景，例如"用于清洗CSV格式的原始数据"
    PLUGIN_VERSION = None  # 插件的版本号，遵循语义化版本规范（如"1.0.0"），用于版本管理和兼容性判断

    def __init__(self):
        """
        插件实例的构造方法，负责插件的初始化流程控制
        
        执行逻辑：
        1. 首先验证子类是否完整实现了元数据（名称、描述、版本）
        2. 若元数据不完整，抛出ValueError异常阻止实例化
        3. 元数据验证通过后，依次调用初始化方法和钩子注册方法
        确保插件在使用前完成必要的准备工作
        """
        # 使用all()函数检查三个元数据字段是否都有值（非None）
        # 若存在任何一个未定义的字段，触发异常
        if not all([self.PLUGIN_NAME, self.PLUGIN_DESCRIPTION, self.PLUGIN_VERSION]):
            raise ValueError("Plugin metadata (PLUGIN_NAME, PLUGIN_DESCRIPTION, PLUGIN_VERSION) must be defined.")
        
        # 调用插件初始化方法，执行子类自定义的初始化逻辑
        self.init_plugin()
        # 调用钩子注册方法，让子类注册需要监听的系统事件
        self.register_hooks()

    def init_plugin(self):
        """
        插件初始化的具体实现方法，用于执行插件启动前的准备工作
        
        基类默认实现：
        - 输出一条INFO级别的日志，提示插件已完成初始化
        子类可重写此方法实现特定逻辑，例如：
        - 加载配置文件
        - 建立数据库连接
        - 初始化缓存数据结构等
        注意：重写时若需要保留默认日志，可通过super().init_plugin()调用父类方法
        """
        # 记录插件初始化成功的日志，包含插件名称便于追踪
        logger.info(f'{self.PLUGIN_NAME} initialized.')

    def register_hooks(self):
        """
        插件钩子注册方法，用于将插件功能与系统事件关联
        
        钩子（Hook）机制说明：
        系统在运行过程中会触发一系列事件（如"数据处理前"、"任务完成后"等），
        插件通过注册钩子，可以在特定事件发生时自动执行对应逻辑。
        
        基类默认实现：空方法（pass）
        子类需根据自身功能重写此方法，例如：
        - 调用系统提供的register_hook()方法注册事件回调
        - 定义需要监听的事件类型和对应的处理函数
        """
        pass

    def get_plugin_info(self):
        """
        获取插件元数据的统一接口，用于系统展示或管理插件信息
        
        返回值说明：
        - 字典类型，包含三个键值对
        - 'name'：对应PLUGIN_NAME
        - 'description'：对应PLUGIN_DESCRIPTION
        - 'version'：对应PLUGIN_VERSION
        
        应用场景：
        - 插件管理界面展示插件列表
        - 系统启动时收集所有插件信息进行校验
        - 插件间依赖关系判断时获取版本信息
        """
        return {
            'name': self.PLUGIN_NAME,
            'description': self.PLUGIN_DESCRIPTION,
            'version': self.PLUGIN_VERSION
        }