#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
日誌管理模組

Author: PANJIT IT Team
Created: 2024-01-28
Modified: 2024-01-28
"""

import logging
import os
from pathlib import Path
from logging.handlers import RotatingFileHandler
from flask import current_app, has_request_context, request, g


def get_logger(name):
    """取得指定名稱的日誌器"""
    logger = logging.getLogger(name)
    
    # 避免重複設定 handler
    if not logger.handlers:
        setup_logger(logger)
    
    return logger


def setup_logger(logger):
    """設定日誌器"""
    if has_request_context() and current_app:
        log_level = current_app.config.get('LOG_LEVEL', 'INFO')
        log_file = current_app.config.get('LOG_FILE', 'logs/app.log')
    else:
        log_level = os.environ.get('LOG_LEVEL', 'INFO')
        log_file = os.environ.get('LOG_FILE', 'logs/app.log')
    
    # 確保日誌目錄存在
    log_path = Path(log_file)
    log_path.parent.mkdir(parents=True, exist_ok=True)
    
    # 設定日誌等級
    logger.setLevel(getattr(logging, log_level.upper()))
    
    # 建立格式化器
    formatter = logging.Formatter(
        '%(asctime)s [%(levelname)s] %(name)s: %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S'
    )
    
    # 檔案處理器（使用輪轉）
    file_handler = RotatingFileHandler(
        log_file,
        maxBytes=10*1024*1024,  # 10MB
        backupCount=5,
        encoding='utf-8'
    )
    file_handler.setLevel(getattr(logging, log_level.upper()))
    file_handler.setFormatter(formatter)
    logger.addHandler(file_handler)
    
    # 控制台處理器
    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.INFO)
    console_handler.setFormatter(formatter)
    logger.addHandler(console_handler)


class DatabaseLogHandler(logging.Handler):
    """資料庫日誌處理器"""
    
    def emit(self, record):
        """發送日誌記錄到資料庫"""
        try:
            from app.models.log import SystemLog
            
            # 取得使用者和任務資訊（如果有的話）
            user_id = None
            job_id = None
            extra_data = {}
            
            if has_request_context():
                user_id = g.get('current_user_id')
                extra_data.update({
                    'method': request.method,
                    'endpoint': request.endpoint,
                    'url': request.url,
                    'ip_address': request.remote_addr,
                    'user_agent': request.headers.get('User-Agent')
                })
            
            # 儲存到資料庫
            SystemLog.log(
                level=record.levelname,
                module=record.name,
                message=record.getMessage(),
                user_id=user_id,
                job_id=job_id,
                extra_data=extra_data if extra_data else None
            )
            
        except Exception:
            # 避免日誌記錄失敗影響主程序
            pass


def init_logging(app):
    """初始化應用程式日誌"""
    # 設定根日誌器
    root_logger = logging.getLogger()
    root_logger.setLevel(logging.INFO)
    
    # 添加資料庫日誌處理器（僅對重要日誌）
    if app.config.get('SQLALCHEMY_DATABASE_URI'):
        db_handler = DatabaseLogHandler()
        db_handler.setLevel(logging.WARNING)  # 只記錄警告以上等級到資料庫
        root_logger.addHandler(db_handler)
    
    # 設定 Flask 應用日誌
    if not app.logger.handlers:
        setup_logger(app.logger)
    
    # 設定第三方庫日誌等級
    logging.getLogger('werkzeug').setLevel(logging.WARNING)
    logging.getLogger('urllib3').setLevel(logging.WARNING)
    logging.getLogger('requests').setLevel(logging.WARNING)