"""{{ display_name }} MCP server — generated by mcpify. Do not hand-edit.

`structlog` configuration: JSON output (pretty on an interactive TTY),
level from `{{ tool_prefix_env }}_LOG_LEVEL` (default `"info"`), and
automatic redaction of sensitive fields (REQ-2.3.1) via a processor —
structlog's processor chain is a first-class fit for this, no separate
sanitizer module needed the way other targets require one.
"""

from __future__ import annotations

import logging
import os
import sys
from typing import Any

import structlog

LOG_LEVEL_ENV_VAR = "{{ tool_prefix_env }}_LOG_LEVEL"

_REDACTED_KEYS = {
    "password",
    "token",
    "secret",
    "api_key",
    "apikey",
    "authorization",
    "client_secret",
    "consumer_secret",
    "private_key",
    "access_token",
    "refresh_token",
}
_REDACTED_VALUE = "[REDACTED]"


def resolve_log_level() -> str:
    return os.environ.get(LOG_LEVEL_ENV_VAR, "info")


def redact(data: dict[str, Any]) -> dict[str, Any]:
    """Shallow-redacts sensitive fields from an arbitrary dict — the same
    field list `_redact_sensitive_fields` applies to log events, reused by
    `cli/config.py` (Story P5) so `{{ project_name }} config` never prints
    a raw secret to the terminal.
    """
    return {
        key: (_REDACTED_VALUE if key.lower() in _REDACTED_KEYS else value)
        for key, value in data.items()
    }


def _redact_sensitive_fields(
    _logger: Any, _method_name: str, event_dict: dict[str, Any]
) -> dict[str, Any]:
    for key in event_dict:
        if key.lower() in _REDACTED_KEYS:
            event_dict[key] = _REDACTED_VALUE
    return event_dict


def init_logging() -> None:
    """Installs the process-global structured logger. Call once, at
    process startup, before any `structlog.get_logger()` call elsewhere.
    """
    level = getattr(logging, resolve_log_level().upper(), logging.INFO)
    renderer = (
        structlog.dev.ConsoleRenderer()
        if sys.stderr.isatty()
        else structlog.processors.JSONRenderer()
    )

    structlog.configure(
        processors=[
            structlog.contextvars.merge_contextvars,
            structlog.processors.add_log_level,
            structlog.processors.TimeStamper(fmt="iso"),
            _redact_sensitive_fields,
            structlog.processors.StackInfoRenderer(),
            structlog.processors.format_exc_info,
            renderer,
        ],
        wrapper_class=structlog.make_filtering_bound_logger(level),
        context_class=dict,
        logger_factory=structlog.PrintLoggerFactory(file=sys.stderr),
        cache_logger_on_first_use=True,
    )


def get_logger(name: str | None = None) -> structlog.stdlib.BoundLogger:
    return structlog.get_logger(name)
