"""Structured logging helpers.

When used as a library (e.g. imported by auto_iac), no handlers are attached
by default so the package does not write to stderr and does not interfere
with the calling application's UI (e.g. Rich live panels). Callers can attach
their own handler to the \"azure_discovery\" logger if they want to see logs.

When run as the CLI, the entrypoint calls enable_cli_logging() so logs are
emitted to stderr in JSON form.
"""

from __future__ import annotations

import json
import logging
import os
import sys
from typing import Any

_LOGGER_NAME = "azure_discovery"


def _build_json_formatter() -> logging.Formatter:
    class JsonFormatter(logging.Formatter):
        def format(self, record: logging.LogRecord) -> str:
            payload: dict[str, Any] = {
                "logger": record.name,
                "level": record.levelname,
                "message": record.getMessage(),
                "module": record.module,
                "function": record.funcName,
            }
            if record.exc_info:
                payload["exc_info"] = self.formatException(record.exc_info)
            if record.__dict__.get("context"):
                payload["context"] = record.__dict__["context"]
            return json.dumps(payload)

    return JsonFormatter()


def get_logger(quiet: bool = False) -> logging.Logger:
    """Return module-wide logger. Does not attach any handler when used as a library.

    Library use: no output unless the calling app attaches a handler to
    \"azure_discovery\". CLI use: call enable_cli_logging() first so logs go to stderr.

    Args:
        quiet: Ignored when no CLI handler is attached. When enable_cli_logging(quiet=True)
            is used, only ERROR and above are emitted.
    """
    logger = logging.getLogger(_LOGGER_NAME)
    if logger.handlers:
        if quiet:
            logger.setLevel(logging.ERROR)
        return logger

    # Library default: no stderr output; avoid interfering with calling scripts.
    logger.addHandler(logging.NullHandler())
    logger.propagate = False
    if quiet:
        logger.setLevel(logging.ERROR)
    else:
        env_level = os.getenv("AZURE_DISCOVERY_LOG_LEVEL", "INFO").upper()
        logger.setLevel(env_level)
    return logger


def enable_cli_logging(quiet: bool = False) -> None:
    """Attach stderr + JSON handler so logs are emitted when run as the CLI.

    Call this from the CLI entrypoint only. When used as a library, do not call
    this so the package does not write to stderr.
    """
    logger = logging.getLogger(_LOGGER_NAME)
    # Replace any existing handlers (e.g. NullHandler from get_logger) with our CLI handler.
    logger.handlers.clear()
    handler = logging.StreamHandler(sys.stderr)
    handler.setFormatter(_build_json_formatter())
    logger.addHandler(handler)
    logger.propagate = False
    if quiet:
        logger.setLevel(logging.ERROR)
    else:
        env_level = os.getenv("AZURE_DISCOVERY_LOG_LEVEL", "INFO").upper()
        logger.setLevel(env_level)
