"""
AbuLang Logging Framework - Built-in logging system
"""

import logging
import sys
from pathlib import Path
from typing import Optional, Dict
from datetime import datetime


class AbuLogger:
    """AbuLang logger"""
    
    def __init__(self, name: str, level: int = logging.INFO):
        self.logger = logging.getLogger(name)
        self.logger.setLevel(level)
        self.handlers = []
    
    def add_console_handler(self, level: int = logging.INFO):
        """Add console output handler"""
        handler = logging.StreamHandler(sys.stdout)
        handler.setLevel(level)
        formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
        )
        handler.setFormatter(formatter)
        self.logger.addHandler(handler)
        self.handlers.append(handler)
    
    def add_file_handler(self, filename: str, level: int = logging.INFO):
        """Add file output handler"""
        handler = logging.FileHandler(filename)
        handler.setLevel(level)
        formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
        )
        handler.setFormatter(formatter)
        self.logger.addHandler(handler)
        self.handlers.append(handler)
    
    def debug(self, message: str):
        """Log debug message"""
        self.logger.debug(message)
    
    def info(self, message: str):
        """Log info message"""
        self.logger.info(message)
    
    def warning(self, message: str):
        """Log warning message"""
        self.logger.warning(message)
    
    def error(self, message: str):
        """Log error message"""
        self.logger.error(message)
    
    def critical(self, message: str):
        """Log critical message"""
        self.logger.critical(message)
    
    def set_level(self, level: int):
        """Set logging level"""
        self.logger.setLevel(level)
    
    def clear_handlers(self):
        """Clear all handlers"""
        for handler in self.handlers:
            self.logger.removeHandler(handler)
        self.handlers.clear()


class LoggingFramework:
    """Main logging framework"""
    
    def __init__(self):
        self.loggers: Dict[str, AbuLogger] = {}
        self.log_dir = Path("./logs")
        self._ensure_log_dir()
    
    def _ensure_log_dir(self):
        """Create logs directory"""
        self.log_dir.mkdir(exist_ok=True)
    
    def get_logger(self, name: str, level: int = logging.INFO) -> AbuLogger:
        """Get or create logger"""
        if name not in self.loggers:
            logger = AbuLogger(name, level)
            self.loggers[name] = logger
        return self.loggers[name]
    
    def setup_default_logger(self, name: str = "abulang") -> AbuLogger:
        """Setup default logger with console and file output"""
        logger = self.get_logger(name)
        logger.add_console_handler()
        
        log_file = self.log_dir / f"{name}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log"
        logger.add_file_handler(str(log_file))
        
        return logger
    
    def get_all_loggers(self) -> Dict[str, AbuLogger]:
        """Get all loggers"""
        return self.loggers.copy()
    
    def set_global_level(self, level: int):
        """Set level for all loggers"""
        for logger in self.loggers.values():
            logger.set_level(level)
    
    def clear_all(self):
        """Clear all loggers"""
        for logger in self.loggers.values():
            logger.clear_handlers()
        self.loggers.clear()


class ContextLogger:
    """Logger with context information"""
    
    def __init__(self, logger: AbuLogger):
        self.logger = logger
        self.context: Dict = {}
    
    def set_context(self, **kwargs):
        """Set context variables"""
        self.context.update(kwargs)
    
    def log(self, level: int, message: str):
        """Log with context"""
        context_str = " | ".join(f"{k}={v}" for k, v in self.context.items())
        full_message = f"[{context_str}] {message}" if context_str else message
        
        if level == logging.DEBUG:
            self.logger.debug(full_message)
        elif level == logging.INFO:
            self.logger.info(full_message)
        elif level == logging.WARNING:
            self.logger.warning(full_message)
        elif level == logging.ERROR:
            self.logger.error(full_message)
        elif level == logging.CRITICAL:
            self.logger.critical(full_message)
    
    def debug(self, message: str):
        """Log debug with context"""
        self.log(logging.DEBUG, message)
    
    def info(self, message: str):
        """Log info with context"""
        self.log(logging.INFO, message)
    
    def warning(self, message: str):
        """Log warning with context"""
        self.log(logging.WARNING, message)
    
    def error(self, message: str):
        """Log error with context"""
        self.log(logging.ERROR, message)
    
    def critical(self, message: str):
        """Log critical with context"""
        self.log(logging.CRITICAL, message)


# Global logging framework
_logging_framework = LoggingFramework()


def get_logging_framework() -> LoggingFramework:
    """Get global logging framework"""
    return _logging_framework


def get_logger(name: str) -> AbuLogger:
    """Get logger"""
    return _logging_framework.get_logger(name)
