import logging
import logging.config
from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
    from snakestack.config import SnakeStackSettings


def setup_logging(
    settings: "SnakeStackSettings"
) -> None:
    filters = {
        "request_id": {"()": "snakestack.logging.filters.RequestIdFilter"},
        "excluded_name": {
            "()": "snakestack.logging.filters.ExcludeLoggerFilter",
            "excluded_name": settings.logging.filter_excluded_name
        },
        "path_filter": {
            "()": "snakestack.logging.filters.PathFilter",
            "paths": settings.logging.filter_paths
        }
    }

    third_party_formatter = (
        "default"
        if settings.logging.formatter == "with_request_id"
        else settings.logging.formatter
    )

    handlers = {
        "console": {
            "class": "logging.StreamHandler",
            "formatter": settings.logging.formatter,
            "filters": settings.logging.filters,
        },
        "third_party_console": {
            "class": "logging.StreamHandler",
            "formatter": third_party_formatter
        },
    }

    formatters = {
        "default": {
            "format": "%(asctime)s [%(levelname)s] %(name)s: %(message)s"
        },
        "with_request_id": {
            "format": (
                "%(asctime)s [%(levelname)s] [req_id=%(request_id)s] "
                "%(name)s: %(message)s"
            )
        },
        "json": {
            "()": "snakestack.logging.formatters.JsonFormatter"
        }
    }

    logging_config: dict[str, Any] = {
        "version": 1,
        "disable_existing_loggers": False,
        "formatters": formatters,
        "handlers": handlers,
        "filters": filters,
        "loggers": {
            settings.logging.name: {
                "level": settings.logging.level,
                "handlers": ["console"],
                "propagate": False,
            },
            "snakestack": {
                "level": settings.logging.level,
                "handlers": ["console"],
                "propagate": False,
            }
        },
        "root": {
            "level": settings.logging.lib_level,
            "handlers": ["console"]
        }
    }

    logging.config.dictConfig(logging_config)
