import socket
from logging import Logger
from typing import Any, Callable, Dict, Optional, Sequence

from botocore.compat import ensure_bytes as ensure_bytes
from botocore.compat import ensure_unicode as ensure_unicode
from botocore.compat import urlparse as urlparse
from botocore.hooks import BaseEventHooks
from botocore.model import OperationModel
from botocore.retryhandler import EXCEPTION_MAP as RETRYABLE_EXCEPTIONS

logger: Logger = ...

class Monitor:
    def __init__(self, adapter: Any, publisher: Any) -> None: ...
    def register(self, event_emitter: BaseEventHooks) -> None: ...
    def capture(self, event_name: str, **payload: Any) -> None: ...

class MonitorEventAdapter:
    def __init__(self, time: Callable[[], float] = ...) -> None: ...
    def feed(
        self, emitter_event_name: str, emitter_payload: Dict[str, Any]
    ) -> BaseMonitorEvent: ...

class BaseMonitorEvent:
    def __init__(self, service: str, operation: str, timestamp: int) -> None:
        self.service: str = ...
        self.operation: str = ...
        self.timestamp: int = ...

    def __eq__(self, other: Any) -> bool: ...

class APICallEvent(BaseMonitorEvent):
    def __init__(
        self,
        service: str,
        operation: OperationModel,
        timestamp: int,
        latency: Optional[int] = ...,
        attempts: Optional[Sequence[APICallAttemptEvent]] = ...,
        retries_exceeded: bool = ...,
    ) -> None:
        self.latency: int = ...
        self.attempts: Sequence[APICallAttemptEvent] = ...
        self.retries_exceeded: bool = ...

    def new_api_call_attempt(self, timestamp: int) -> APICallAttemptEvent: ...

class APICallAttemptEvent(BaseMonitorEvent):
    def __init__(
        self,
        service: str,
        operation: OperationModel,
        timestamp: int,
        latency: Optional[int] = ...,
        url: Optional[str] = ...,
        http_status_code: Optional[int] = ...,
        request_headers: Optional[Dict[str, Any]] = ...,
        response_headers: Optional[Dict[str, Any]] = ...,
        parsed_error: Optional[Dict[str, Any]] = ...,
        wire_exception: Optional[Exception] = ...,
    ) -> None:
        self.latency: Optional[int] = ...
        self.url: Optional[str] = ...
        self.http_status_code: Optional[int] = ...
        self.request_headers: Optional[Dict[str, Any]] = ...
        self.response_headers: Optional[Dict[str, Any]] = ...
        self.parsed_error: Optional[Dict[str, Any]] = ...
        self.wire_exception: Optional[Exception] = ...

class CSMSerializer:
    def __init__(self, csm_client_id: str) -> None:
        self.csm_client_id: str = ...

    def serialize(self, event: BaseMonitorEvent) -> bytes: ...

class SocketPublisher:
    def __init__(self, socket: socket.socket, host: str, port: int, serializer: Any) -> None: ...
    def publish(self, event: BaseMonitorEvent) -> None: ...
