"""
混合日志处理器 - 结合大小和时间轮转的优势
"""

import os
from logging.handlers import TimedRotatingFileHandler


class HybridRotatingFileHandler(TimedRotatingFileHandler):
    """
    混合轮转文件处理器
    结合时间轮转和大小轮转的优点
    """
    
    def __init__(self, filename, when='D', interval=1, backupCount=30,
                 maxBytes=50*1024*1024, encoding='utf-8', **kwargs):
        """
        初始化混合轮转处理器
        
        Args:
            filename: 日志文件名
            when: 时间轮转单位 ('S', 'M', 'H', 'D', 'W0'-'W6', 'midnight')（默认按天轮转）
            interval: 轮转间隔 （默认每天轮转一次）
            backupCount: 保留的备份文件数量（默认保留30个的日志）
            maxBytes: 单个文件最大字节数(默认50MB)
            encoding: 文件编码
        """
        super().__init__(filename, when=when, interval=interval, 
                        backupCount=backupCount, encoding=encoding, **kwargs)
        self.maxBytes = maxBytes
        self.current_file_size = 0
        
    def shouldRollover(self, record):
        """
        判断是否需要轮转
        同时检查时间和大小条件
        """
        # 检查时间条件（继承自 TimedRotatingFileHandler）
        if super().shouldRollover(record):
            return True
            
        # 检查文件大小条件
        if self.maxBytes > 0:
            if not hasattr(self, 'stream') or self.stream is None:
                self.stream = self._open()
                
            msg = "%s\n" % self.format(record)
            self.current_file_size += len(msg.encode(self.encoding or 'utf-8'))
            
            if self.current_file_size >= self.maxBytes:
                return True
                
        return False
        
    def doRollover(self):
        """
        执行轮转操作
        """
        # 重置当前文件大小计数器
        self.current_file_size = 0
        
        # 执行时间轮转
        super().doRollover()
        
        # 清理过期文件（如果需要额外的清理逻辑）
        self._cleanup_old_files()
        
    def _cleanup_old_files(self):
        """
        清理过期的日志文件
        """
        if self.backupCount > 0:
            # 获取所有相关的日志文件
            dir_name, base_name = os.path.split(self.baseFilename)
            file_names = os.listdir(dir_name)
            result = []
            
            # 筛选出属于当前日志的文件
            prefix = base_name + "."
            plen = len(prefix)
            
            for file_name in file_names:
                if file_name[:plen] == prefix:
                    suffix = file_name[plen:]
                    if self.extMatch.match(suffix):
                        result.append(os.path.join(dir_name, file_name))
                        
            # 按修改时间排序并删除多余的文件
            if len(result) > self.backupCount:
                result.sort()
                for s in result[:-self.backupCount]:
                    os.remove(s)

