"""Lightweight stdout logger for environments where stdlib logging is swallowed."""

from __future__ import annotations

import os
import sys
import threading
import time
import traceback
from typing import Any


class PrintLogger:
    def __init__(self, name: str, *, enabled: bool = True):
        self.name = name
        self.enabled = enabled

    def set_enabled(self, enabled: bool) -> None:
        self.enabled = enabled

    def child(self, *, name: str | None = None, enabled: bool | None = None) -> "PrintLogger":
        return PrintLogger(
            name or self.name,
            enabled=self.enabled if enabled is None else enabled,
        )

    def _format(self, msg: str, *args: Any) -> str:
        if args:
            try:
                return msg % args
            except Exception:
                return f"{msg} | args={args!r}"
        return msg

    def _emit(self, level: str, msg: str, *args: Any, exc_info: bool = False) -> None:
        if not self.enabled:
            return
        timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        thread = threading.current_thread()
        line = (
            f"{timestamp} {level} [{os.getpid()}:{thread.name}:{thread.ident}] "
            f"{self.name} {self._format(msg, *args)}"
        )
        print(line, file=sys.stdout, flush=True)
        if exc_info:
            exc = traceback.format_exc()
            if exc and exc.strip() != 'NoneType: None':
                print(exc.rstrip(), file=sys.stdout, flush=True)

    def debug(self, msg: str, *args: Any, exc_info: bool = False) -> None:
        self._emit('DEBUG', msg, *args, exc_info=exc_info)

    def info(self, msg: str, *args: Any, exc_info: bool = False) -> None:
        self._emit('INFO', msg, *args, exc_info=exc_info)

    def warning(self, msg: str, *args: Any, exc_info: bool = False) -> None:
        self._emit('WARNING', msg, *args, exc_info=exc_info)

    def error(self, msg: str, *args: Any, exc_info: bool = False) -> None:
        self._emit('ERROR', msg, *args, exc_info=exc_info)

    def exception(self, msg: str, *args: Any) -> None:
        self._emit('ERROR', msg, *args, exc_info=True)
