Загрузка данных


#!/usr/bin/env python3
# -*- coding: utf-8 -*-


from __future__ import annotations

import abc
import argparse
import atexit
import contextlib
import contextvars
import dataclasses
import datetime
import enum
import functools
import hashlib
import json
import logging
import sys
import threading
import time
import traceback
import uuid
from typing import (
    Any,
    Callable,
    Dict,
    Final,
    FrozenSet,
    Generic,
    Iterable,
    List,
    Mapping,
    Optional,
    Protocol,
    Sequence,
    Tuple,
    Type,
    TypeVar,
    cast,
    final,
    runtime_checkable,
)


__version__: Final[str] = "1.0.0"
__all__: Final[Tuple[str, ...]] = (
    "Greeting",
    "RenderRequest",
    "RenderResult",
    "HelloWorldApplication",
    "ServiceContainer",
    "EventBus",
    "build_application",
    "main",
)


# =============================================================================
# РАЗДЕЛ 1. Константы предметной области
# =============================================================================

DEFAULT_SALUTATION: Final[str] = "Hello"
DEFAULT_TARGET: Final[str] = "World"
DEFAULT_PUNCTUATION: Final[str] = "!"

MAX_SALUTATION_LENGTH: Final[int] = 128
MAX_TARGET_LENGTH: Final[int] = 256
MIN_PUNCTUATION_LENGTH: Final[int] = 1

LOGGER_NAME: Final[str] = "hello_world"
LOGGER: Final[logging.Logger] = logging.getLogger(LOGGER_NAME)

_METRIC_LOCK: Final[threading.Lock] = threading.Lock()


# =============================================================================
# РАЗДЕЛ 2. Иерархия исключений предметной области
# =============================================================================

class HelloWorldError(Exception):
    """Базовый класс всех ошибок предметной области.

    Каждая ошибка снабжается уникальным идентификатором, что позволяет
    коррелировать сообщения пользователя с записями журнала.
    """

    def __init__(
        self,
        message: str,
        *,
        details: Optional[Mapping[str, Any]] = None,
    ) -> None:
        super().__init__(message)
        self.message: str = message
        self.details: Mapping[str, Any] = dict(details or {})
        self.error_id: str = uuid.uuid4().hex
        self.occurred_at: datetime.datetime = datetime.datetime.now(
            datetime.timezone.utc
        )

    def to_dict(self) -> Dict[str, Any]:
        """Сериализует ошибку в словарь для структурного журнала."""
        return {
            "error_id": self.error_id,
            "type": type(self).__name__,
            "message": self.message,
            "details": dict(self.details),
            "occurred_at": self.occurred_at.isoformat(),
        }

    def __str__(self) -> str:
        base = f"[{self.error_id[:8]}] {self.message}"
        if self.details:
            rendered = ", ".join(f"{key}={value!r}" for key, value in self.details.items())
            return f"{base} ({rendered})"
        return base


class ConfigurationError(HelloWorldError):
    """Ошибка конфигурации приложения, обнаруженная при сборке контейнера."""


class ValidationError(HelloWorldError):
    """Нарушение инвариантов value object ``Greeting``."""


class CompositeValidationError(ValidationError):
    """Агрегированная ошибка, объединяющая несколько нарушений валидации."""

    def __init__(self, errors: Sequence[ValidationError]) -> None:
        flattened: List[str] = [error.message for error in errors]
        super().__init__(
            "Обнаружено нарушений валидации: " + "; ".join(flattened),
            details={"count": len(errors)},
        )
        self.errors: Tuple[ValidationError, ...] = tuple(errors)


class ProviderNotFoundError(ConfigurationError):
    """Запрошенный провайдер отсутствует в реестре."""


class DependencyNotFoundError(ConfigurationError):
    """Зависимость не зарегистрирована в контейнере инверсии зависимостей."""


class CircularDependencyError(ConfigurationError):
    """Обнаружена циклическая зависимость при резолюции сервисов."""


class RenderingError(HelloWorldError):
    """Ошибка на этапе формирования итогового сообщения."""


class ChannelClosedError(HelloWorldError):
    """Попытка записи в закрытый канал вывода."""


class RetryBudgetExhaustedError(HelloWorldError):
    """Все повторные попытки выполнения операции исчерпаны."""


class InvalidStateTransitionError(HelloWorldError):
    """Попытка нелегального перехода в жизненном цикле приложения."""


# =============================================================================
# РАЗДЕЛ 3. Перечисления (enums)
# =============================================================================

class OutputChannelType(enum.Enum):
    """Тип канала вывода сообщения."""

    STDOUT = "stdout"
    STDERR = "stderr"
    BUFFER = "buffer"


class MessageFormat(enum.Enum):
    """Стратегия форматирования текста сообщения."""

    PLAIN = "plain"
    UPPER = "upper"
    LOWER = "lower"
    TITLE = "title"
    SHOUTING = "shouting"


class Verbosity(enum.IntEnum):
    """Уровень детализации сопутствующего вывода."""

    QUIET = 0
    NORMAL = 1
    VERBOSE = 2
    DEBUG = 3


class ServiceLifetime(enum.Enum):
    """Время жизни сервиса в контейнере зависимостей."""

    SINGLETON = "singleton"
    TRANSIENT = "transient"


class LifecycleState(enum.Enum):
    """Этапы жизненного цикла приложения."""

    CREATED = "created"
    INITIALIZED = "initialized"
    RUNNING = "running"
    COMPLETED = "completed"
    FAILED = "failed"

    def allows_transition_to(self, other: "LifecycleState") -> bool:
        """Проверяет, является ли переход ``self -> other`` легальным."""
        allowed: Mapping[LifecycleState, FrozenSet[LifecycleState]] = {
            LifecycleState.CREATED: {LifecycleState.INITIALIZED, LifecycleState.FAILED},
            LifecycleState.INITIALIZED: {LifecycleState.RUNNING, LifecycleState.FAILED},
            LifecycleState.RUNNING: {LifecycleState.COMPLETED, LifecycleState.FAILED},
            LifecycleState.COMPLETED: frozenset(),
            LifecycleState.FAILED: frozenset(),
        }
        return other in allowed[self]


# =============================================================================
# РАЗДЕЛ 4. Неизменяемые value objects
# =============================================================================

@final
@dataclasses.dataclass(frozen=True, repr=True)
class Greeting:
    """Неизменяемое представление приветствия.

    Атрибуты:
        salutation: приветственная фраза (например, «Hello»).
        target: адресат приветствия (например, «World»).
        punctuation: завершающая пунктуация.
    """

    salutation: str = DEFAULT_SALUTATION
    target: str = DEFAULT_TARGET
    punctuation: str = DEFAULT_PUNCTUATION

    def __post_init__(self) -> None:
        """Проверяет инварианты value object в момент создания."""
        if not isinstance(self.salutation, str) or not self.salutation.strip():
            raise ValidationError("Параметр salutation должен быть непустой строкой")
        if not isinstance(self.target, str) or not self.target.strip():
            raise ValidationError("Параметр target должен быть непустой строкой")
        if len(self.salutation) > MAX_SALUTATION_LENGTH:
            raise ValidationError(
                "Длина salutation превышает допустимую",
                details={"limit": MAX_SALUTATION_LENGTH},
            )
        if len(self.target) > MAX_TARGET_LENGTH:
            raise ValidationError(
                "Длина target превышает допустимую",
                details={"limit": MAX_TARGET_LENGTH},
            )
        if len(self.punctuation) < MIN_PUNCTUATION_LENGTH:
            raise ValidationError("Пунктуация не может быть пустой")

    def compose(self) -> str:
        """Собирает каноническую строку приветствия."""
        return f"{self.salutation}, {self.target}{self.punctuation}"

    def to_dict(self) -> Dict[str, str]:
        """Возвращает словарное представление для сериализации."""
        return {
            "salutation": self.salutation,
            "target": self.target,
            "punctuation": self.punctuation,
        }


@final
@dataclasses.dataclass(frozen=True)
class RenderRequest:
    """Неизменяемый снимок параметров одного рендеринга."""

    greeting: Greeting
    message_format: MessageFormat = MessageFormat.PLAIN
    verbosity: Verbosity = Verbosity.NORMAL
    correlation_id: str = dataclasses.field(default_factory=lambda: uuid.uuid4().hex)


@final
@dataclasses.dataclass(frozen=True)
class RenderResult:
    """Иммутабельный результат рендеринга и доставки сообщения."""

    payload: str
    byte_length: int
    checksum: str
    duration_ms: float
    correlation_id: str

    def to_dict(self) -> Dict[str, Any]:
        """Подготавливает результат к сериализации в JSON."""
        return {
            "payload": self.payload,
            "byte_length": self.byte_length,
            "checksum": self.checksum,
            "duration_ms": round(self.duration_ms, 4),
            "correlation_id": self.correlation_id,
        }


# =============================================================================
# РАЗДЕЛ 5. Протоколы (структурные интерфейсы)
# =============================================================================

@runtime_checkable
class MessageFormatter(Protocol):
    """Стратегия преобразования текста сообщения."""

    def format(self, text: str) -> str:
        """Преобразует текст сообщения согласно правилам стратегии."""
        ...


@runtime_checkable
class OutputChannel(Protocol):
    """Абстракция канала доставки сообщения."""

    @property
    def is_open(self) -> bool:
        """Признак того, что канал открыт для записи."""
        ...

    def emit(self, payload: str) -> None:
        """Доставляет полезную нагрузку в канал."""
        ...

    def flush(self) -> None:
        """Сбрасывает буферы канала."""
        ...


@runtime_checkable
class Clock(Protocol):
    """Абстракция источника времени — необходима для детерминированных тестов."""

    def now(self) -> datetime.datetime:
        """Возвращает текущие дата и время с часовым поясом."""
        ...

    def monotonic(self) -> float:
        """Возвращает монотонные часы в секундах."""
        ...


@runtime_checkable
class TelemetrySink(Protocol):
    """Абстракция приёмника телеметрических метрик."""

    def record(self, metric: str, value: float, tags: Mapping[str, str]) -> None:
        """Регистрирует значение метрики с произвольными тегами."""
        ...


# =============================================================================
# РАЗДЕЛ 6. Абстрактные базовые классы предметной области
# =============================================================================

class GreetingProvider(abc.ABC):
    """Поставщик приветствий: единственная точка получения доменных данных."""

    REGISTRY_KEY: str = ""

    @abc.abstractmethod
    def provide(self) -> Greeting:
        """Возвращает валидное приветствие."""
        raise NotImplementedError

    def describe(self) -> str:
        """Человекочитаемое описание провайдера (может быть переопределено)."""
        return f"{type(self).__name__}(key={self.REGISTRY_KEY!r})"


class RenderingStrategy(abc.ABC):
    """Абстрактная стратегия превращения запроса в строку."""

    @abc.abstractmethod
    def render(self, request: RenderRequest) -> str:
        """Выполняет рендеринг сообщения по переданному запросу."""
        raise NotImplementedError


class Validator(abc.ABC):
    """Абстрактный валидатор приветствий."""

    @abc.abstractmethod
    def validate(self, greeting: Greeting) -> None:
        """Поднимает ``ValidationError``, если инварианты нарушены."""
        raise NotImplementedError


# =============================================================================
# РАЗДЕЛ 7. Реестр провайдеров на основе метакласса
# =============================================================================

class ProviderRegistryMeta(abc.ABCMeta):
    """Метакласс, автоматически регистрирующий конкретных провайдеров.

    Любой класс-наследник ``GreetingProvider``, реализовавший все абстрактные
    методы и объявивший непустой ``REGISTRY_KEY``, попадает в реестр без
    какого-либо дополнительного кода со стороны разработчика.
    """

    _registry: Dict[str, Type["GreetingProvider"]] = {}

    def __init__(
        cls,
        name: str,
        bases: Tuple[type, ...],
        namespace: Dict[str, Any],
    ) -> None:
        super().__init__(name, bases, namespace)
        abstract: FrozenSet[str] = getattr(cls, "__abstractmethods__", frozenset())
        key: str = getattr(cls, "REGISTRY_KEY", "")
        if not abstract and key:
            ProviderRegistryMeta._registry[key] = cls
            LOGGER.debug("Провайдер %s зарегистрирован под ключом %r", name, key)

    @classmethod
    def get(cls, key: str) -> Type["GreetingProvider"]:
        """Возвращает класс провайдера по ключу или поднимает ошибку."""
        try:
            return ProviderRegistryMeta._registry[key]
        except KeyError:
            raise ProviderNotFoundError(
                "Провайдер не найден",
                details={"key": key, "available": sorted(ProviderRegistryMeta._registry)},
            ) from None

    @classmethod
    def keys(cls) -> Tuple[str, ...]:
        """Возвращает отсортированный перечень доступных ключей."""
        return tuple(sorted(ProviderRegistryMeta._registry))


class RegisteredGreetingProvider(GreetingProvider, metaclass=ProviderRegistryMeta):
    """Базовый класс с метаклассом-реестром; сам по себе нерегистрируется."""


@final
class DefaultGreetingProvider(RegisteredGreetingProvider):
    """Канонический провайдер: «Hello, World!»."""

    REGISTRY_KEY = "default"

    def provide(self) -> Greeting:
        """Возвращает классическое приветствие всемирно известного образца."""
        return Greeting(
            salutation=DEFAULT_SALUTATION,
            target=DEFAULT_TARGET,
            punctuation=DEFAULT_PUNCTUATION,
        )


@final
class FormalGreetingProvider(RegisteredGreetingProvider):
    """Вежливый провайдер с увеличенной пунктуацией."""

    REGISTRY_KEY = "formal"

    def provide(self) -> Greeting:
        """Возвращает вежливое приветствие."""
        return Greeting(salutation="Good day", target="dear World", punctuation=".")


@final
class EnthusiasticGreetingProvider(RegisteredGreetingProvider):
    """Эмоционально окрашенный провайдер."""

    REGISTRY_KEY = "enthusiastic"

    def provide(self) -> Greeting:
        """Возвращает приветствие с восторженной пунктуацией."""
        return Greeting(salutation="Hello", target="Wonderful World", punctuation="!!!")


# =============================================================================
# РАЗДЕЛ 8. Конкретные реализации стратегий форматирования
# =============================================================================

class PlainFormatter:
    """Стратегия, не изменяющая текст (стратегия по умолчанию)."""

    def format(self, text: str) -> str:
        """Возвращает текст без изменений."""
        return text


class UpperFormatter:
    """Стратегия, переводящая текст в верхний регистр."""

    def format(self, text: str) -> str:
        """Возвращает текст в верхнем регистре."""
        return text.upper()


class LowerFormatter:
    """Стратегия, переводящая текст в нижний регистр."""

    def format(self, text: str) -> str:
        """Возвращает текст в нижнем регистре."""
        return text.lower()


class TitleFormatter:
    """Стратегия, приводящая текст к «заглавному» регистру."""

    def format(self, text: str) -> str:
        """Возвращает текст в регистре Title Case."""
        return text.title()


class ShoutingFormatter:
    """Стратегия, имитирующая крик (верхний регистр + многоточие)."""

    def format(self, text: str) -> str:
        """Возвращает текст, написанный капсом через дефис."""
        separator: Final[str] = "-"
        return separator.join(text.upper())


FORMATTER_REGISTRY: Final[Mapping[MessageFormat, Callable[[], MessageFormatter]]] = {
    MessageFormat.PLAIN: PlainFormatter,
    MessageFormat.UPPER: UpperFormatter,
    MessageFormat.LOWER: LowerFormatter,
    MessageFormat.TITLE: TitleFormatter,
    MessageFormat.SHOUTING: ShoutingFormatter,
}


def create_formatter(message_format: MessageFormat) -> MessageFormatter:
    """Фабричная функция, возвращающая стратегию по значению перечисления."""
    try:
        factory = FORMATTER_REGISTRY[message_format]
    except KeyError:
        raise ConfigurationError(
            "Неизвестный формат сообщения",
            details={"format": message_format},
        ) from None
    formatter = factory()
    LOGGER.debug("Создана стратегия форматирования: %s", type(formatter).__name__)
    return formatter


# =============================================================================
# РАЗДЕЛ 9. Реализации часов
# =============================================================================

@final
class SystemClock:
    """Реальная реализация часов на основе модуля ``datetime`` и ``time``."""

    def now(self) -> datetime.datetime:
        """Возвращает текущие UTC-дата и время."""
        return datetime.datetime.now(datetime.timezone.utc)

    def monotonic(self) -> float:
        """Возвращает значение монотонных часов."""
        return time.perf_counter()


@final
class FrozenClock:
    """Детерминированные часы для воспроизводимых тестов."""

    def __init__(self, instant: datetime.datetime) -> None:
        self._instant: datetime.datetime = instant
        self._ticks: float = 0.0

    def now(self) -> datetime.datetime:
        """Возвращает зафиксированное значение времени."""
        return self._instant

    def monotonic(self) -> float:
        """Возвращает искусственно увеличивающееся значение."""
        self._ticks += 1.0
        return self._ticks


# =============================================================================
# РАЗДЕЛ 10. Каналы вывода
# =============================================================================

class AbstractOutputChannel:
    """Общая логика каналов вывода: состояние, счётчики, блокировки."""

    def __init__(self, name: str) -> None:
        self._name: str = name
        self._open: bool = True
        self._emitted: int = 0
        self._lock: threading.RLock = threading.RLock()

    @property
    def name(self) -> str:
        """Наименование канала (используется в журнале и метриках)."""
        return self._name

    @property
    def is_open(self) -> bool:
        """Признак открытого канала."""
        with self._lock:
            return self._open

    @property
    def emitted_count(self) -> int:
        """Число успешно доставленных сообщений."""
        with self._lock:
            return self._emitted

    def close(self) -> None:
        """Закрывает канал, запрещая дальнейшую запись."""
        with self._lock:
            self._open = False
            LOGGER.debug("Канал %s закрыт", self._name)

    def _ensure_open(self) -> None:
        """Поднимает ``ChannelClosedError``, если канал закрыт."""
        if not self.is_open:
            raise ChannelClosedError(
                "Канал вывода закрыт",
                details={"channel": self._name},
            )

    def _account_emitted(self) -> None:
        """Инкрементирует счётчик доставленных сообщений потокобезопасно."""
        with self._lock:
            self._emitted += 1

    def flush(self) -> None:
        """Переопределяется производными классами при наличии буферов."""
        return None


@final
class StandardOutputChannel(AbstractOutputChannel):
    """Канал, записывающий сообщения в ``sys.stdout``."""

    def __init__(self) -> None:
        super().__init__("stdout")

    def emit(self, payload: str) -> None:
        """Записывает строку в стандартный поток вывода и сбрасывает буфер."""
        self._ensure_open()
        sys.stdout.write(payload + "\n")
        sys.stdout.flush()
        self._account_emitted()
        LOGGER.debug("Доставлено в stdout: %r", payload)

    def flush(self) -> None:
        """Сбрасывает буфер стандартного потока вывода."""
        sys.stdout.flush()


@final
class StandardErrorChannel(AbstractOutputChannel):
    """Канал, записывающий сообщения в ``sys.stderr``."""

    def __init__(self) -> None:
        super().__init__("stderr")

    def emit(self, payload: str) -> None:
        """Записывает строку в поток ошибок."""
        self._ensure_open()
        sys.stderr.write(payload + "\n")
        sys.stderr.flush()
        self._account_emitted()


@final
class BufferChannel(AbstractOutputChannel):
    """Канал, накапливающий сообщения в памяти (для тестов и батчинга)."""

    def __init__(self) -> None:
        super().__init__("buffer")
        self._buffer: List[str] = []

    def emit(self, payload: str) -> None:
        """Накапливает полезную нагрузку во внутреннем буфере."""
        self._ensure_open()
        with self._lock:
            self._buffer.append(payload)
        self._account_emitted()

    def drain(self) -> Tuple[str, ...]:
        """Извлекает и очищает содержимое буфера."""
        with self._lock:
            drained = tuple(self._buffer)
            self._buffer.clear()
        return drained


CHANNEL_FACTORIES: Final[Mapping[OutputChannelType, Callable[[], AbstractOutputChannel]]] = {
    OutputChannelType.STDOUT: StandardOutputChannel,
    OutputChannelType.STDERR: StandardErrorChannel,
    OutputChannelType.BUFFER: BufferChannel,
}


def create_channel(channel_type: OutputChannelType) -> AbstractOutputChannel:
    """Фабричная функция создания канала вывода."""
    try:
        factory = CHANNEL_FACTORIES[channel_type]
    except KeyError:
        raise ConfigurationError(
            "Неизвестный тип канала вывода", details={"channel": channel_type}
        ) from None
    return factory()


# =============================================================================
# РАЗДЕЛ 11. Цепочка ответственности: валидаторы
# =============================================================================

class NonEmptyValidator(Validator):
    """Проверяет, что salutation и target не состоят только из пробелов."""

    def validate(self, greeting: Greeting) -> None:
        """Поднимает ошибку при пустых составных частях."""
        for attribute in ("salutation", "target"):
            value = getattr(greeting, attribute)
            if not value.strip():
                raise ValidationError(
                    "Поле обязательно к заполнению", details={"field": attribute}
                )


class LengthLimitValidator(Validator):
    """Проверяет ограничения на длину составных частей."""

    def validate(self, greeting: Greeting) -> None:
        """Поднимает ошибку при превышении лимитов длины."""
        limits = (("salutation", MAX_SALUTATION_LENGTH), ("target", MAX_TARGET_LENGTH))
        for attribute, limit in limits:
            if len(getattr(greeting, attribute)) > limit:
                raise ValidationError(
                    "Превышен допустимый размер поля",
                    details={"field": attribute, "limit": limit},
                )


class AsciiOnlyValidator(Validator):
    """Пример валидатора, который по умолчанию отключён (пустой контракт)."""

    def validate(self, greeting: Greeting) -> None:
        """Явно ничего не делает: нелокализованный ввод разрешён."""
        return None


class ValidationChain:
    """Цепочка ответственности, агрегирующая всех валидаторов.

    Все ошибки собираются и передаются пользователю одной пачкой — так удобнее,
    чем чинить по одной за каждый прогон.
    """

    def __init__(self, validators: Sequence[Validator]) -> None:
        self._validators: Tuple[Validator, ...] = tuple(validators)

    @property
    def size(self) -> int:
        """Число зарегистрированных валидаторов."""
        return len(self._validators)

    def validate(self, greeting: Greeting) -> None:
        """Выполняет все проверки, агрегируя ошибки в ``CompositeValidationError``."""
        errors: List[ValidationError] = []
        for validator in self._validators:
            try:
                validator.validate(greeting)
            except ValidationError as exc:
                LOGGER.debug(
                    "Валидатор %s сообщил об ошибке: %s",
                    type(validator).__name__,
                    exc.message,
                )
                errors.append(exc)
        if errors:
            raise CompositeValidationError(errors)
        LOGGER.debug("Валидация приветствия завершена успешно (%d проверок)", self.size)


def build_default_validation_chain() -> ValidationChain:
    """Собирает каноническую цепочку валидаторов."""
    return ValidationChain((NonEmptyValidator(), LengthLimitValidator(), AsciiOnlyValidator()))


# =============================================================================
# РАЗДЕЛ 12. Стратегии рендеринга
# =============================================================================

class CompositeRenderingStrategy(RenderingStrategy):
    """Композитная стратегия: сборка → форматирование → контроль качества."""

    def __init__(self, formatter: MessageFormatter) -> None:
        self._formatter: MessageFormatter = formatter

    def render(self, request: RenderRequest) -> str:
        """Выполняет поэтапный рендеринг сообщения."""
        try:
            raw = request.greeting.compose()
        except Exception as exc:
            raise RenderingError(
                "Не удалось собрать исходную строку приветствия",
                details={"reason": str(exc)},
            ) from exc

        formatted = self._formatter.format(raw)
        if not formatted:
            raise RenderingError("Результат форматирования пуст")
        LOGGER.debug(
            "Рендеринг завершён: исходный=%r, итоговый=%r", raw, formatted
        )
        return formatted


# =============================================================================
# РАЗДЕЛ 13. Телеметрия
# =============================================================================

@final
class InMemoryTelemetrySink:
    """Потокобезопасное хранилище метрик в памяти."""

    def __init__(self) -> None:
        self._storage: Dict[Tuple[str, Tuple[Tuple[str, str], ...]], List[float]] = {}
        self._lock: threading.RLock = threading.RLock()

    def record(self, metric: str, value: float, tags: Mapping[str, str]) -> None:
        """Регистрирует значение метрики с нормализованными тегами."""
        key = (metric, tuple(sorted(tags.items())))
        with self._lock:
            self._storage.setdefault(key, []).append(value)

    def snapshot(self) -> Dict[str, Any]:
        """Возвращает снимок агрегированных метрик."""
        with self._lock:
            result: Dict[str, Any] = {}
            for (metric, tags), values in sorted(self._storage.items()):
                tag_map = dict(tags)
                result[f"{metric}|{tag_map}"] = {
                    "count": len(values),
                    "sum": round(sum(values), 6),
                    "min": round(min(values), 6),
                    "max": round(max(values), 6),
                    "avg": round(sum(values) / len(values), 6),
                }
            return result


# =============================================================================
# РАЗДЕЛ 14. Шина событий (наблюдатель)
# =============================================================================

@final
@dataclasses.dataclass(frozen=True)
class Event:
    """Неизменяемое событие предметной области."""

    name: str
    payload: Mapping[str, Any] = dataclasses.field(default_factory=dict)
    occurred_at: datetime.datetime = dataclasses.field(
        default_factory=lambda: datetime.datetime.now(datetime.timezone.utc)
    )
    event_id: str = dataclasses.field(default_factory=lambda: uuid.uuid4().hex)


EventHandler = Callable[[Event], None]


class EventBus:
    """Потокобезопасная шина событий с изоляцией отказов подписчиков."""

    def __init__(self, clock: Optional[Clock] = None) -> None:
        self._subscribers: Dict[str, List[EventHandler]] = {}
        self._lock: threading.RLock = threading.RLock()
        self._clock: Clock = clock or SystemClock()
        self._published: int = 0

    def subscribe(self, event_name: str, handler: EventHandler) -> Callable[[], None]:
        """Подписывает обработчик и возвращает функцию отписки."""
        with self._lock:
            self._subscribers.setdefault(event_name, []).append(handler)
        LOGGER.debug("Подписчик добавлен на событие %r", event_name)

        def unsubscribe() -> None:
            with self._lock:
                handlers = self._subscribers.get(event_name, [])
                if handler in handlers:
                    handlers.remove(handler)

        return unsubscribe

    def publish(self, event: Event) -> int:
        """Публикует событие, возвращая число успешно обработанных подписок."""
        with self._lock:
            handlers = tuple(self._subscribers.get(event.name, ()))
            self._published += 1
        succeeded = 0
        for handler in handlers:
            try:
                handler(event)
                succeeded += 1
            except Exception:
                LOGGER.exception(
                    "Отказ подписчика %r события %r не прервал публикацию",
                    getattr(handler, "__qualname__", repr(handler)),
                    event.name,
                )
        return succeeded

    @property
    def published_count(self) -> int:
        """Общее число опубликованных событий."""
        with self._lock:
            return self._published


def metric_recorder(sink: TelemetrySink, clock: Clock) -> EventHandler:
    """Создаёт обработчик, превращающий события в метрики длительности."""

    def handler(event: Event) -> None:
        duration = event.payload.get("duration_ms")
        if isinstance(duration, (int, float)):
            sink.record("event.duration_ms", float(duration), {"event": event.name})
        else:
            sink.record("event.count", 1.0, {"event": event.name})

    return handler


def console_announcer(event: Event) -> None:
    """Демонстрационный подписчик: печатает вспомогательные сообщения."""
    LOGGER.info("Событие: %s", event.name)


# =============================================================================
# РАЗДЕЛ 15. Декораторы сопровождения (cross-cutting concerns)
# =============================================================================

_CORRELATION_ID: contextvars.ContextVar[str] = contextvars.ContextVar(
    "correlation_id", default=""
)


@contextlib.contextmanager
def trace_context(correlation_id: str) -> Iterable[str]:
    """Устанавливает корреляционный идентификатор в контексте выполнения."""
    token = _CORRELATION_ID.set(correlation_id)
    try:
        yield correlation_id
    finally:
        _CORRELATION_ID.reset(token)


def traced(
    func: Callable[..., Any],
) -> Callable[..., Any]:
    """Декоратор трассировки: журнал входа, выхода и длительности операции."""

    @functools.wraps(func)
    def wrapper(*args: Any, **kwargs: Any) -> Any:
        started = time.perf_counter()
        LOGGER.debug("Вход в %s", func.__qualname__)
        try:
            result = func(*args, **kwargs)
        except Exception as exc:
            LOGGER.warning(
                "Исключение в %s после %.3f мс: %s",
                func.__qualname__,
                (time.perf_counter() - started) * 1000.0,
                exc,
            )
            raise
        LOGGER.debug(
            "Выход из %s за %.3f мс",
            func.__qualname__,
            (time.perf_counter() - started) * 1000.0,
        )
        return result

    return wrapper


def retry(
    max_attempts: int = 3,
    base_delay: float = 0.001,
    retry_on: Tuple[Type[BaseException], ...] = (Exception,),
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """Декоратор повторов с экспоненциальной задержкой.

    После исчерпания бюджета повторов поднимается ``RetryBudgetExhaustedError``.
    """

    if max_attempts < 1:
        raise ConfigurationError("max_attempts должен быть не меньше единицы")

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        @functools.wraps(func)
        def wrapper(*args: Any, **kwargs: Any) -> Any:
            last_exception: Optional[BaseException] = None
            for attempt in range(1, max_attempts + 1):
                try:
                    return func(*args, **kwargs)
                except retry_on as exc:  # type: ignore[misc]
                    last_exception = exc
                    delay = base_delay * (2 ** (attempt - 1))
                    LOGGER.warning(
                        "Попытка %d/%d операции %s не удалась: %s; повтор через %.4f с",
                        attempt,
                        max_attempts,
                        func.__qualname__,
                        exc,
                        delay,
                    )
                    time.sleep(delay)
            raise RetryBudgetExhaustedError(
                "Бюджет повторов исчерпан",
                details={"attempts": max_attempts, "last_error": str(last_exception)},
            ) from last_exception

        return wrapper

    return decorator


def lru_cached(maxsize: int = 128) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
    """Декоратор кэширования с явно указанным размером кэша."""

    def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
        return functools.lru_cache(maxsize=maxsize)(func)

    return decorator


# =============================================================================
# РАЗДЕЛ 16. Контейнер инверсии зависимостей
# =============================================================================

T = TypeVar("T")


@final
@dataclasses.dataclass(frozen=True)
class ServiceDescriptor:
    """Описание сервиса: как его создать и как долго он живёт."""

    interface: type
    factory: Callable[["ServiceContainer"], Any]
    lifetime: ServiceLifetime


class ServiceContainer:
    """Миниатюрный контейнер внедрения зависимостей с поддержкой жизненных циклов.

    Возможности:
        * регистрация готовых singleton-инстансов;
        * регистрация фабрик (singleton / transient);
        * обнаружение циклических зависимостей;
        * потокобезопасная резолюция.
    """

    def __init__(self) -> None:
        self._descriptors: Dict[type, ServiceDescriptor] = {}
        self._instances: Dict[type, Any] = {}
        self._resolution_stack: List[type] = []
        self._lock: threading.RLock = threading.RLock()

    def register_instance(self, interface: Type[T], instance: T) -> "ServiceContainer":
        """Регистрирует готовый экземпляр как singleton."""
        with self._lock:
            self._instances[interface] = instance
        LOGGER.debug("Зарегистрирован инстанс для %s", interface.__name__)
        return self

    def register_singleton(
        self,
        interface: Type[T],
        factory: Callable[["ServiceContainer"], T],
    ) -> "ServiceContainer":
        """Регистрирует фабрику singleton-сервиса."""
        return self._register(interface, factory, ServiceLifetime.SINGLETON)

    def register_transient(
        self,
        interface: Type[T],
        factory: Callable[["ServiceContainer"], T],
    ) -> "ServiceContainer":
        """Регистрирует фабрику transient-сервиса."""
        return self._register(interface, factory, ServiceLifetime.TRANSIENT)

    def _register(
        self,
        interface: type,
        factory: Callable[["ServiceContainer"], Any],
        lifetime: ServiceLifetime,
    ) -> "ServiceContainer":
        if not isinstance(interface, type):
            raise ConfigurationError("Интерфейс должен быть классом")
        with self._lock:
            self._descriptors[interface] = ServiceDescriptor(interface, factory, lifetime)
        LOGGER.debug(
            "Зарегистрирован сервис %s (время жизни: %s)",
            interface.__name__,
            lifetime.value,
        )
        return self

    def resolve(self, interface: Type[T]) -> T:
        """Резолвит сервис, рекурсивно разрешая его зависимости."""
        with self._lock:
            return cast(T, self._resolve_locked(interface))

    def _resolve_locked(self, interface: type) -> Any:
        if interface in self._instances:
            return self._instances[interface]

        descriptor = self._descriptors.get(interface)
        if descriptor is None:
            raise DependencyNotFoundError(
                "Сервис не зарегистрирован в контейнере",
                details={"service": getattr(interface, "__name__", str(interface))},
            )

        if interface in self._resolution_stack:
            chain = [item.__name__ for item in self._resolution_stack]
            chain.append(interface.__name__)
            raise CircularDependencyError(
                "Обнаружена циклическая зависимость",
                details={"chain": " -> ".join(chain)},
            )

        self._resolution_stack.append(interface)
        try:
            instance = descriptor.factory(self)
            if descriptor.lifetime is ServiceLifetime.SINGLETON:
                self._instances[interface] = instance
            return instance
        finally:
            self._resolution_stack.pop()

    def diagnostics(self) -> Dict[str, Any]:
        """Возвращает статистику контейнера для отладочных целей."""
        with self._lock:
            return {
                "registered": sorted(name.__name__ for name in self._descriptors),
                "materialized": sorted(name.__name__ for name in self._instances),
            }


# =============================================================================
# РАЗДЕЛ 17. Оркестратор предметной области
# =============================================================================

@final
class HelloWorldApplication:
    """Главный оркестратор: валидирует, рендерит, доставляет и отчитывается."""

    def __init__(
        self,
        provider: GreetingProvider,
        strategy: RenderingStrategy,
        channel: AbstractOutputChannel,
        validators: ValidationChain,
        bus: EventBus,
        telemetry: TelemetrySink,
        clock: Clock,
    ) -> None:
        self._provider: GreetingProvider = provider
        self._strategy: RenderingStrategy = strategy
        self._channel: AbstractOutputChannel = channel
        self._validators: ValidationChain = validators
        self._bus: EventBus = bus
        self._telemetry: TelemetrySink = telemetry
        self._clock: Clock = clock
        self._state: LifecycleState = LifecycleState.CREATED
        self._runs: int = 0
        LOGGER.debug("Приложение %s создано", type(self).__name__)

    # -- Инкапсуляция состояния -------------------------------------------------

    @property
    def state(self) -> LifecycleState:
        """Текущий этап жизненного цикла приложения."""
        return self._state

    @property
    def runs(self) -> int:
        """Число успешно выполненных запусков."""
        return self._runs

    def _transition(self, target: LifecycleState) -> None:
        """Выполняет переход состояния с проверкой легальности."""
        if not self._state.allows_transition_to(target):
            raise InvalidStateTransitionError(
                "Нелегальный переход жизненного цикла",
                details={"from": self._state.value, "to": target.value},
            )
        LOGGER.debug("Переход состояния: %s -> %s", self._state.value, target.value)
        self._state = target

    # -- Основной сценарий -------------------------------------------------------

    @traced
    @retry(max_attempts=3, base_delay=0.0005)
    def run(self, request: RenderRequest) -> RenderResult:
        """Исполняет полный сценарий доставки приветствия."""
        if self._state is LifecycleState.CREATED:
            self._transition(LifecycleState.INITIALIZED)
        self._transition(LifecycleState.RUNNING)
        self._runs += 1

        with trace_context(request.correlation_id):
            started = self._clock.monotonic()
            try:
                greeting = self._provider.provide()
                self._validators.validate(greeting)

                actual_request = dataclasses.replace(request, greeting=greeting)
                payload = self._strategy.render(actual_request)

                self._channel.emit(payload)
                self._channel.flush()

                duration_ms = (self._clock.monotonic() - started) * 1000.0
                result = RenderResult(
                    payload=payload,
                    byte_length=len(payload.encode("utf-8")),
                    checksum=hashlib.sha256(payload.encode("utf-8")).hexdigest(),
                    duration_ms=duration_ms,
                    correlation_id=request.correlation_id,
                )
            except Exception as exc:
                self._transition(LifecycleState.FAILED)
                self._bus.publish(
                    Event(
                        name="app.failed",
                        payload={
                            "error": str(exc),
                            "correlation_id": request.correlation_id,
                        },
                    )
                )
                self._telemetry.record("run.failures", 1.0, {"provider": type(self._provider).__name__})
                raise

            self._transition(LifecycleState.COMPLETED)
            self._bus.publish(
                Event(
                    name="message.emitted",
                    payload={
                        "duration_ms": duration_ms,
                        "byte_length": result.byte_length,
                        "channel": self._channel.name,
                    },
                )
            )
            self._telemetry.record(
                "run.duration_ms",
                duration_ms,
                {"provider": type(self._provider).__name__, "channel": self._channel.name},
            )
            LOGGER.info(
                "Приветствие доставлено: %s (%d байт, %.3f мс)",
                result.payload,
                result.byte_length,
                result.duration_ms,
            )
            return result

    # -- Контекстное управление --------------------------------------------------

    @contextlib.contextmanager
    def session(self) -> Iterable["HelloWorldApplication"]:
        """Контекстный менеджер, гарантирующий закрытие канала вывода."""
        try:
            yield self
        finally:
            self._channel.close()
            LOGGER.debug("Сессия приложения завершена")


# =============================================================================
# РАЗДЕЛ 18. Конфигурация и сборка приложения (composition root)
# =============================================================================

@final
@dataclasses.dataclass(frozen=True)
class ApplicationConfig:
    """Иммутабельная конфигурация приложения."""

    provider_key: str = "default"
    message_format: MessageFormat = MessageFormat.PLAIN
    channel_type: OutputChannelType = OutputChannelType.STDOUT
    verbosity: Verbosity = Verbosity.NORMAL
    output_json: bool = False


def configure_logging(verbosity: Verbosity) -> None:
    """Настраивает корневой логгер модуля в зависимости от детализации."""
    levels: Mapping[Verbosity, int] = {
        Verbosity.QUIET: logging.ERROR,
        Verbosity.NORMAL: logging.WARNING,
        Verbosity.VERBOSE: logging.INFO,
        Verbosity.DEBUG: logging.DEBUG,
    }
    handler = logging.StreamHandler(stream=sys.stderr)
    handler.setFormatter(
        logging.Formatter(
            fmt="%(asctime)s | %(levelname)-8s | %(name)s | %(message)s",
            datefmt="%Y-%m-%dT%H:%M:%S",
        )
    )
    LOGGER.handlers.clear()
    LOGGER.addHandler(handler)
    LOGGER.setLevel(levels[verbosity])
    LOGGER.propagate = False


def build_container(config: ApplicationConfig) -> ServiceContainer:
    """Собирает контейнер зависимостей (composition root)."""
    container = ServiceContainer()

    container.register_instance(Clock, SystemClock())
    container.register_instance(TelemetrySink, InMemoryTelemetrySink())

    container.register_singleton(ValidationChain, lambda c: build_default_validation_chain())
    container.register_singleton(
        GreetingProvider,
        lambda c: ProviderRegistryMeta.get(config.provider_key)(),
    )
    container.register_singleton(
        MessageFormatter,
        lambda c: create_formatter(config.message_format),
    )
    container.register_singleton(
        RenderingStrategy,
        lambda c: CompositeRenderingStrategy(c.resolve(MessageFormatter)),
    )
    container.register_singleton(
        AbstractOutputChannel,
        lambda c: create_channel(config.channel_type),
    )
    container.register_singleton(EventBus, lambda c: EventBus(c.resolve(Clock)))
    return container


def build_application(container: ServiceContainer) -> HelloWorldApplication:
    """Создаёт оркестратор, извлекая все зависимости из контейнера."""
    bus = container.resolve(EventBus)
    telemetry = container.resolve(TelemetrySink)
    clock = container.resolve(Clock)
    bus.subscribe("message.emitted", metric_recorder(telemetry, clock))
    bus.subscribe("app.failed", metric_recorder(telemetry, clock))
    if LOGGER.isEnabledFor(logging.INFO):
        bus.subscribe("message.emitted", console_announcer)

    return HelloWorldApplication(
        provider=container.resolve(GreetingProvider),
        strategy=container.resolve(RenderingStrategy),
        channel=container.resolve(AbstractOutputChannel),
        validators=container.resolve(ValidationChain),
        bus=bus,
        telemetry=telemetry,
        clock=clock,
    )


def build_request(config: ApplicationConfig) -> RenderRequest:
    """Формирует запрос рендеринга из конфигурации."""
    return RenderRequest(
        greeting=Greeting(),
        message_format=config.message_format,
        verbosity=config.verbosity,
    )


# =============================================================================
# РАЗДЕЛ 19. Самопроверочный набор тестов (self-test)
# =============================================================================

class SelfTestSuite:
    """Набор проверок, подтверждающих работоспособность без фреймворков."""

    def __init__(self) -> None:
        self._passed: int = 0
        self._failed: int = 0

    def check(self, condition: bool, name: str) -> None:
        """Фиксирует результат одной проверки."""
        if condition:
            self._passed += 1
            print(f"  [OK]   {name}")
        else:
            self._failed += 1
            print(f"  [FAIL] {name}")

    def run_all(self) -> int:
        """Исполняет все проверки и возвращает код завершения."""
        print("Запуск самопроверочного набора...")
        previous_level = logging.root.manager.disable
        logging.disable(logging.CRITICAL)  # тесты намеренно провоцируют отказы
        try:
            self.test_greeting_composition()
            self.test_greeting_invariants()
            self.test_formatters()
            self.test_validators()
            self.test_registry()
            self.test_container_circular_detection()
            self.test_event_bus_isolation()
            self.test_buffer_channel()
            self.test_end_to_end()
        finally:
            logging.disable(previous_level)
        print(f"Итог: пройдено {self._passed}, провалено {self._failed}")
        return 0 if self._failed == 0 else 1

    def test_greeting_composition(self) -> None:
        greeting = Greeting()
        self.check(greeting.compose() == "Hello, World!", "Канонический состав: Hello, World!")

    def test_greeting_invariants(self) -> None:
        try:
            Greeting(salutation="   ")
            self.check(False, "Пустая salutation отклоняется")
        except ValidationError:
            self.check(True, "Пустая salutation отклоняется")

    def test_formatters(self) -> None:
        self.check(create_formatter(MessageFormat.UPPER).format("ab") == "AB", "Верхний регистр")
        self.check(create_formatter(MessageFormat.LOWER).format("AB") == "ab", "Нижний регистр")
        self.check(create_formatter(MessageFormat.PLAIN).format("x") == "x", "Неизменный текст")

    def test_validators(self) -> None:
        chain = build_default_validation_chain()
        try:
            chain.validate(Greeting())
            self.check(True, "Валидация корректного приветствия")
        except ValidationError:
            self.check(False, "Валидация корректного приветствия")

    def test_registry(self) -> None:
        keys = ProviderRegistryMeta.keys()
        self.check("default" in keys, "Реестр содержит провайдер default")
        self.check(ProviderRegistryMeta.get("default") is DefaultGreetingProvider, "Ключ default резолвится")

    def test_container_circular_detection(self) -> None:
        class A:
            def __init__(self, container: "ServiceContainer") -> None:
                self.b = container.resolve("B")  # type: ignore[arg-type]

        container = ServiceContainer()
        container.register_singleton(A, lambda c: A(c))
        try:
            container.resolve(A)
            self.check(False, "Циклические зависимости обнаруживаются")
        except (CircularDependencyError, DependencyNotFoundError):
            self.check(True, "Циклические зависимости обнаруживаются")

    def test_event_bus_isolation(self) -> None:
        bus = EventBus(SystemClock())
        bus.subscribe("x", lambda e: (_ for _ in ()).throw(RuntimeError("boom")))
        delivered = bus.publish(Event(name="x"))
        self.check(delivered == 0, "Отказ подписчика не прерывает публикацию")

    def test_buffer_channel(self) -> None:
        channel = BufferChannel()
        channel.emit("ping")
        self.check(channel.drain() == ("ping",), "Буферный канал накапливает сообщения")

    def test_end_to_end(self) -> None:
        config = ApplicationConfig(channel_type=OutputChannelType.BUFFER)
        container = build_container(config)
        application = build_application(container)
        result = application.run(build_request(config))
        channel = container.resolve(AbstractOutputChannel)
        buffer = cast(BufferChannel, channel)
        self.check(result.payload == "Hello, World!", "Сквозной сценарий печатает Hello, World!")
        self.check(buffer.drain() == ("Hello, World!",), "Канал получил ровно одно сообщение")
        self.check(len(result.checksum) == 64, "Контрольная сумма SHA-256 вычислена")


# =============================================================================
# РАЗДЕЛ 20. Интерфейс командной строки и точка входа
# =============================================================================

def parse_args(argv: Optional[Sequence[str]] = None) -> argparse.Namespace:
    """Разбирает аргументы командной строки."""
    parser = argparse.ArgumentParser(
        prog="hello_world_overengineered",
        description="Самый заинжиниренный вывод Hello, World! в истории.",
    )
    parser.add_argument("--provider", default="default", help="Ключ провайдера приветствия")
    parser.add_argument(
        "--format",
        dest="message_format",
        default="plain",
        choices=[item.value for item in MessageFormat],
        help="Стратегия форматирования",
    )
    parser.add_argument(
        "--channel",
        default="stdout",
        choices=[item.value for item in OutputChannelType],
        help="Канал вывода",
    )
    parser.add_argument("--json", action="store_true", help="Вывод результата в формате JSON")
    parser.add_argument("-v", "--verbose", action="count", default=0, help="Уровень детализации")
    parser.add_argument("--self-test", action="store_true", help="Запустить самопроверку")
    return parser.parse_args(argv)


def config_from_args(args: argparse.Namespace) -> ApplicationConfig:
    """Преобразует разобранные аргументы в типизированную конфигурацию."""
    verbosity = Verbosity.NORMAL + min(args.verbose, len(Verbosity) - 1)
    return ApplicationConfig(
        provider_key=args.provider,
        message_format=MessageFormat(args.message_format),
        channel_type=OutputChannelType(args.channel),
        verbosity=Verbosity(verbosity),
        output_json=bool(args.json),
    )


def main(argv: Optional[Sequence[str]] = None) -> int:
    """Точка входа приложения."""
    args = parse_args(argv)

    if args.self_test:
        return SelfTestSuite().run_all()

    config = config_from_args(args)
    if config.output_json and config.channel_type is OutputChannelType.STDOUT:
        # В JSON-режиме stdout принадлежит исключительно структурированному
        # результату, поэтому сообщение уходит в буферный канал.
        config = dataclasses.replace(config, channel_type=OutputChannelType.BUFFER)
    configure_logging(config.verbosity)
    LOGGER.info("Инициализация приложения, версия %s", __version__)

    container = build_container(config)
    application = build_application(container)
    atexit.register(lambda: LOGGER.info("Контейнер: %s", container.diagnostics()))

    try:
        with application.session():
            result = application.run(build_request(config))
    except HelloWorldError as exc:
        print(json.dumps(exc.to_dict(), ensure_ascii=False), file=sys.stderr)
        return 2
    except Exception:
        traceback.print_exc()
        return 70

    # Сообщение уже доставлено каналом вывода, поэтому здесь мы лишь
    # отчитываемся о метаданных рендеринга, если об этом просили.
    if config.output_json:
        print(json.dumps(result.to_dict(), ensure_ascii=False, indent=2))
    return 0


if __name__ == "__main__":
    sys.exit(main())