from __future__ import annotations

import logging

from opendeviationbar.config.sidecar import SidecarConfig

from .checkpoint import _extract_checkpoints

logger = logging.getLogger(__name__)


def _restart_engine_with_recovery(
    engine: object,
    config: SidecarConfig,
    trace_id: str,
    bars_written: int,
    restart_attempt: int,
    valid_pairs: set[tuple[str, int]] | None = None,
) -> tuple[object | None, bool, dict[tuple[str, int], int], dict[str, str], object | None, str]:
    """Restart engine with timeout guards and error recovery (Issue #318).

    Each shutdown step has isolated error handling to prevent cascading failures.

    Returns:
        (new_engine, success_bool, min_tid_guard, symbol_modes, ch_cache,
        rust_ch_writer_mode)
        engine is None, symbol_modes is empty dict, ch_cache is None,
        and rust_ch_writer_mode is "off" if restart failed.
    """
    try:
        # Step 1: Graceful shutdown attempt (may fail or hang)
        try:
            engine.stop()
            logger.info("engine.stop() completed")
        except (RuntimeError, OSError, TimeoutError, ValueError) as e:
            logger.warning("engine.stop() raised exception: %s", e)

        # Step 2: Extract checkpoints (critical for state recovery)
        try:
            _extract_checkpoints(engine, trace_id, bars_written)
            logger.info("checkpoint extraction succeeded")
        except (OSError, ValueError, RuntimeError) as e:
            logger.warning("checkpoint extraction failed: %s", e)

        # Step 3: Force shutdown
        try:
            engine.shutdown()
            logger.info("engine.shutdown() completed")
        except (RuntimeError, OSError, TimeoutError, ValueError) as e:
            logger.warning("engine.shutdown() raised: %s", e)

        # Step 4: Create new engine (fill_from_rest handles gaps via _create_engine)
        # DEFERRED import to avoid circular dependency
        from opendeviationbar.sidecar import _create_engine

        new_engine, _, new_min_tid_guard, new_symbol_modes, new_ch_cache, new_rust_ch_writer_mode = _create_engine(
            config,
            trace_id,
            None,
            valid_pairs=valid_pairs,
        )
        logger.info("engine restart #%d succeeded", restart_attempt)
    except Exception:
        logger.exception("WATCHDOG RESTART FAILED (attempt #%d)", restart_attempt)
        return None, False, {}, {}, None, "off"
    else:
        return new_engine, True, new_min_tid_guard, new_symbol_modes, new_ch_cache, new_rust_ch_writer_mode
