"""ClickHouse cache layer for computed open deviation bars (Issue #78).

This module provides caching for computed open deviation bars (Tier 2) using ClickHouse.
Raw tick data (Tier 1) is stored locally via `opendeviationbar.storage.TickStorage`.

Configuration
-------------
Set environment variables via mise (recommended) or directly:

    # Connection mode (OPENDEVIATIONBAR_MODE)
    export OPENDEVIATIONBAR_MODE=local  # Force localhost:8123 only
    export OPENDEVIATIONBAR_MODE=cloud  # Require CLICKHOUSE_HOST env var
    export OPENDEVIATIONBAR_MODE=auto   # Auto-detect (default)

    # Host configuration (for AUTO/CLOUD modes)
    export OPENDEVIATIONBAR_CH_HOSTS="host1,host2"  # SSH aliases from ~/.ssh/config
    export OPENDEVIATIONBAR_CH_PRIMARY="host1"       # Default host
    export CLICKHOUSE_HOST="localhost"       # Direct host (CLOUD mode)

If no env vars set, falls back to localhost:8123 in AUTO mode.

Example
-------
>>> from opendeviationbar.clickhouse import (
...     OpenDeviationBarCache, get_available_clickhouse_host,
... )
>>> from opendeviationbar import process_trades_to_dataframe_cached
>>>
>>> # Check ClickHouse availability
>>> host = get_available_clickhouse_host()
>>> print(f"Using ClickHouse at {host.host} via {host.method}")
>>>
>>> # Use cached processing
>>> df = process_trades_to_dataframe_cached(trades, symbol="BTCUSDT")

See Also
--------
opendeviationbar.storage.TickStorage : Local Parquet storage for raw tick data
"""

from __future__ import annotations

import os
import warnings

from .cache import CacheKey, OpenDeviationBarCache
from .client import (
    ClickHouseQueryError,
    ClickHouseUnavailableError,
    get_client,
)
from .config import ClickHouseConfig, ConnectionMode, get_connection_mode
from .constants import CLICKHOUSE_TRANSIENT_ERRORS
from .migrations import check_exchange_session_coverage, migrate_exchange_sessions
from .mixin import ClickHouseClientMixin
from .preflight import (
    ClickHouseNotConfiguredError,
    HostConnection,
    InstallationLevel,
    PreflightResult,
    detect_clickhouse_state,
    get_available_clickhouse_host,
)
from .tunnel import SSHTunnel

__all__ = [
    "CLICKHOUSE_TRANSIENT_ERRORS",
    "CacheKey",
    "ClickHouseClientMixin",
    "ClickHouseConfig",
    "ClickHouseNotConfiguredError",
    "ClickHouseQueryError",
    "ClickHouseUnavailableError",
    "ConnectionMode",
    "HostConnection",
    "InstallationLevel",
    "OpenDeviationBarCache",
    "PreflightResult",
    "SSHTunnel",
    "check_exchange_session_coverage",
    "detect_clickhouse_state",
    "get_available_clickhouse_host",
    "get_client",
    "get_connection_mode",
    "migrate_exchange_sessions",
]


def _emit_import_warning() -> None:
    """Emit warning at import time if ClickHouse not ready."""
    try:
        state = detect_clickhouse_state()
        if state.level < InstallationLevel.RUNNING_NO_SCHEMA:
            warnings.warn(
                f"ClickHouse cache not available: {state.message}. "
                f"Cached functions will fail. {state.action_required or ''}",
                UserWarning,
                stacklevel=3,
            )
    except (ImportError, OSError, RuntimeError, ConnectionError):
        pass  # Don't fail import on preflight errors


# Optional: emit warning at import time (can be disabled via env var)
if not os.getenv("OPENDEVIATIONBAR_SKIP_IMPORT_CHECK"):
    _emit_import_warning()
