# Copyright Visual Collaboration Technologies Inc. All Rights Reserved.
# See LICENSE for details.
"""Configures logging handlers and levels."""

import logging
import sys
from pathlib import Path

from .colorlog_formatter import create_formatter as create_colorlog_formatter
from .config import ConsoleLogConfig, FileLogConfig, resolve_message_format
from .custom_level import CustomLevelLogger
from .log_level import decode_log_level

LOGGER_NAME = "vcti"
logger: CustomLevelLogger = logging.getLogger(LOGGER_NAME)  # type: ignore[assignment]


def setup_logging(
    logging_configurations: list[ConsoleLogConfig | FileLogConfig],
    propagate: bool = False,
):
    """
    Configures logging for console and file output.

    Clears all existing handlers on the logger before adding new ones.
    Calling this function again replaces the previous configuration entirely.

    The logger is named ``"vcti"``. Application code that needs its own
    child logger should use ``logging.getLogger("vcti.<name>")``, which
    inherits handlers and levels from the parent.

    Args:
        logging_configurations: List of ConsoleLogConfig or FileLogConfig.
        propagate (bool): Determines if log messages propagate to the root logger.

    Raises:
        ValueError: If an invalid log level is specified.
    """
    # Clear existing handlers before setting up new ones
    for handler in logger.handlers[:]:
        logger.removeHandler(handler)
        handler.close()

    for config in logging_configurations:
        log_level = decode_log_level(config.log_level).value
        handler = None
        if isinstance(config, ConsoleLogConfig):
            # In GUI environments sys.stderr/sys.stdout may be None.
            # Skip the console handler to avoid runtime crashes.
            if sys.stderr is None and sys.stdout is None:
                continue
            stream = sys.stderr if sys.stderr is not None else sys.stdout
            handler = logging.StreamHandler(stream=stream)
            fmt = resolve_message_format(config.message_format, color=config.enable_color_log)
            handler.setFormatter(
                create_colorlog_formatter(message_format=fmt)
                if config.enable_color_log
                else logging.Formatter(fmt=fmt)
            )
        elif isinstance(config, FileLogConfig):
            handler = logging.FileHandler(Path(config.file_path).resolve(), mode=config.mode)
            fmt = resolve_message_format(config.message_format, color=False)
            handler.setFormatter(logging.Formatter(fmt))

        if handler:
            handler.setLevel(log_level)
            logger.addHandler(handler)

    if logger.handlers:
        logger.setLevel(min(h.level for h in logger.handlers))
    else:
        logger.setLevel(logging.NOTSET)
    logger.propagate = propagate
