# Copyright Visual Collaboration Technologies Inc. All Rights Reserved.
# See LICENSE for details.
"""Defines logging configuration parameters using dataclasses."""

from dataclasses import dataclass
from pathlib import Path
from typing import Literal

from .log_level import DEFAULT_LOG_LEVEL_STR, LogLevelStr

MessageFormatPreset = Literal["minimal", "standard", "detailed"]

MESSAGE_FORMAT_PRESETS: dict[str, tuple[str, str]] = {
    # Each entry maps a preset name to (plain_format, color_format).
    "minimal": (
        "%(message)s",
        "%(log_color)s%(message)s",
    ),
    "standard": (
        "%(levelname)s:     %(message)s",
        "%(log_color)s%(levelname)s:     %(reset)s%(message)s",
    ),
    "detailed": (
        "%(levelname)s: %(pathname)s:%(lineno)d   %(message)s",
        "%(log_color)s%(levelname)s: %(pathname)s:%(lineno)d   %(reset)s%(message)s",
    ),
}

DEFAULT_MESSAGE_FORMAT_PRESET: MessageFormatPreset = "standard"


def resolve_message_format(format_or_preset: str | None, *, color: bool = False) -> str:
    """Resolve a message format string from a preset name or raw format.

    Args:
        format_or_preset: A preset name ("minimal", "standard", "detailed"),
            a raw format string, or None (uses DEFAULT_MESSAGE_FORMAT_PRESET).
        color: If True and the value is a preset name, return the color variant.

    Returns:
        A resolved log message format string.
    """
    if format_or_preset is None:
        format_or_preset = DEFAULT_MESSAGE_FORMAT_PRESET
    if format_or_preset in MESSAGE_FORMAT_PRESETS:
        plain, colored = MESSAGE_FORMAT_PRESETS[format_or_preset]
        return colored if color else plain
    return format_or_preset


@dataclass
class ConsoleLogConfig:
    """
    Configuration for console logging.

    Attributes:
        log_level: Logging level (e.g., "info", "debug", "trace").
                  Valid values: notset, trace, debug, verbose, info, warning, error, fatal
        message_format: A preset name ("minimal", "standard", "detailed"),
                       a raw format string, or None (uses default preset).
        enable_color_log: Enables colored logging output.
    """

    log_level: LogLevelStr = DEFAULT_LOG_LEVEL_STR
    message_format: str | None = None
    enable_color_log: bool = False


@dataclass
class FileLogConfig:
    """
    Configuration for file logging.

    Attributes:
        file_path: Path to log file.
        log_level: Logging level (e.g., "info", "debug", "trace").
                  Valid values: notset, trace, debug, verbose, info, warning, error, fatal
        message_format: A preset name ("minimal", "standard", "detailed"),
                       a raw format string, or None (uses default preset).
        mode: File open mode. "a" (append, default) or "w" (overwrite).
    """

    file_path: Path
    log_level: LogLevelStr = DEFAULT_LOG_LEVEL_STR
    message_format: str | None = None
    mode: Literal["a", "w"] = "a"


def create_logging_config(
    enable_console_log: bool = True,
    enable_color_log: bool = False,
    log_file_path: Path | None = None,
    log_level: LogLevelStr = DEFAULT_LOG_LEVEL_STR,
    message_format: str | None = None,
) -> list[ConsoleLogConfig | FileLogConfig]:
    """
    Generates logging configurations.

    Args:
        enable_console_log: Enables console logging.
        enable_color_log: Enables colored console output.
        log_file_path: File path for log storage.
        log_level: Logging level (e.g., "info", "debug", "trace").
                  Valid values: notset, trace, debug, verbose, info, warning, error, fatal
        message_format: A preset name ("minimal", "standard", "detailed"),
                       a raw format string, or None (uses default preset).

    Returns:
        List of configured logging parameters.
    """
    config_list = []
    if enable_console_log:
        config_list.append(
            ConsoleLogConfig(
                log_level=log_level,
                message_format=message_format,
                enable_color_log=enable_color_log,
            )
        )
    if log_file_path:
        config_list.append(
            FileLogConfig(
                file_path=log_file_path,
                log_level=log_level,
                message_format=message_format,
            )
        )
    return config_list
