# -*- coding: utf-8 -*-
"""
Session自动清理服务

定期清理过期的Flask session文件
"""
import os
import time
import threading
import logging
from pathlib import Path
from typing import Optional
from datetime import datetime, timedelta

logger = logging.getLogger(__name__)


class SessionCleaner:
    """Session自动清理器"""
    
    def __init__(self, session_dir: str, session_lifetime: int = 3600, cleanup_interval: int = 3600):
        """
        初始化Session清理器
        
        Args:
            session_dir: Session文件目录
            session_lifetime: Session生命周期（秒），默认1小时
            cleanup_interval: 清理间隔（秒），默认1小时
        """
        self.session_dir = Path(session_dir)
        self.session_lifetime = session_lifetime
        self.cleanup_interval = cleanup_interval
        self._running = False
        self._thread: Optional[threading.Thread] = None
        
    def start(self):
        """启动自动清理线程"""
        if self._running:
            logger.warning("Session清理器已在运行")
            return
        
        self._running = True
        self._thread = threading.Thread(target=self._cleanup_loop, daemon=True)
        self._thread.start()
        logger.info(f"Session自动清理器已启动 (清理间隔: {self.cleanup_interval}秒)")
    
    def stop(self):
        """停止自动清理线程"""
        self._running = False
        if self._thread:
            self._thread.join(timeout=5)
        logger.info("Session自动清理器已停止")
    
    def _cleanup_loop(self):
        """清理循环"""
        while self._running:
            try:
                self.cleanup_expired_sessions()
            except Exception as e:
                logger.error(f"清理Session时出错: {e}", exc_info=True)
            
            # 等待指定间隔
            for _ in range(self.cleanup_interval):
                if not self._running:
                    break
                time.sleep(1)
    
    def cleanup_expired_sessions(self) -> int:
        """
        清理过期的Session文件
        
        Returns:
            清理的文件数量
        """
        if not self.session_dir.exists():
            logger.debug(f"Session目录不存在: {self.session_dir}")
            return 0
        
        deleted_count = 0
        now = time.time()
        # 使用session_lifetime + 1小时作为缓冲，确保完全过期
        cutoff = now - (self.session_lifetime + 3600)
        
        try:
            for session_file in self.session_dir.glob('*'):
                if not session_file.is_file():
                    continue
                
                try:
                    # 检查文件修改时间
                    mtime = session_file.stat().st_mtime
                    if mtime < cutoff:
                        session_file.unlink()
                        deleted_count += 1
                        logger.debug(f"已删除过期Session文件: {session_file.name}")
                except (OSError, PermissionError) as e:
                    logger.warning(f"无法删除Session文件 {session_file.name}: {e}")
                except Exception as e:
                    logger.error(f"处理Session文件 {session_file.name} 时出错: {e}")
            
            if deleted_count > 0:
                logger.info(f"已清理 {deleted_count} 个过期Session文件")
            
        except Exception as e:
            logger.error(f"清理Session文件时出错: {e}", exc_info=True)
        
        return deleted_count
    
    def cleanup_now(self) -> int:
        """立即执行一次清理"""
        return self.cleanup_expired_sessions()

