import logging
import os
import sys

_SYSLOG_PRIORITIES = {
    logging.CRITICAL: 2,
    logging.ERROR: 3,
    logging.WARNING: 4,
    logging.INFO: 6,
    logging.DEBUG: 7,
}


def _parse_log_level(raw_level: str) -> int:
    level_name = raw_level.strip().upper()
    if not level_name:
        message = "LOG_LEVEL must not be empty"
        raise ValueError(message)

    level = logging.getLevelNamesMapping().get(level_name)
    if level is None:
        message = f"LOG_LEVEL has unknown level: {raw_level}"
        raise ValueError(message)
    return level


def _read_bool_env(name: str) -> bool | None:
    value = os.getenv(name)
    if value is None:
        return None

    normalized = value.strip().lower()
    if normalized in {"1", "true", "yes", "on"}:
        return True
    if normalized in {"0", "false", "no", "off"}:
        return False
    message = f"{name} must be a boolean value"
    raise ValueError(message)


def _use_systemd_logging() -> bool:
    force_systemd = _read_bool_env("LOG_SYSTEMD")
    if force_systemd is not None:
        return force_systemd
    return os.getenv("JOURNAL_STREAM") is not None


class _SystemdFormatter(logging.Formatter):
    def format(self, record: logging.LogRecord) -> str:
        message = super().format(record)
        priority = _SYSLOG_PRIORITIES.get(
            record.levelno,
            7 if record.levelno < logging.INFO else 6,
        )
        return f"<{priority}>{message}"


def configure_logging() -> None:
    log_level = _parse_log_level(os.getenv("LOG_LEVEL", "INFO"))
    handler = logging.StreamHandler(stream=sys.stdout)

    formatter = (
        _SystemdFormatter("%(name)s: %(message)s")
        if _use_systemd_logging()
        else logging.Formatter(
            "%(asctime)s %(levelname)s %(name)s: %(message)s",
            datefmt="%Y-%m-%d %H:%M:%S",
        )
    )

    handler.setFormatter(formatter)

    root_logger = logging.getLogger()
    root_logger.handlers.clear()
    root_logger.setLevel(log_level)
    root_logger.addHandler(handler)
