"""Shared bridge connection manager — singleton with async lock."""

from __future__ import annotations

import asyncio
import os
from typing import Optional

from godotiq.bridge.connection import BridgeConnection, BridgeConnectionError

_bridge: Optional[BridgeConnection] = None
_bridge_lock: Optional[asyncio.Lock] = None

DEFAULT_PORT = 6007


async def get_bridge() -> BridgeConnection:
    """Return a connected bridge instance, creating one if needed.

    Lazily initializes the async lock and auto-reconnects if the
    previous connection was lost.
    """
    global _bridge, _bridge_lock

    if _bridge_lock is None:
        _bridge_lock = asyncio.Lock()

    async with _bridge_lock:
        if _bridge is not None and _bridge.is_connected:
            return _bridge

        if _bridge is not None:
            await _bridge.disconnect()

        try:
            port = int(os.environ.get("GODOTIQ_ADDON_PORT", str(DEFAULT_PORT)))
        except (ValueError, TypeError):
            port = DEFAULT_PORT
        _bridge = BridgeConnection(port=port)
        await _bridge.connect()
        return _bridge


async def get_bridge_or_none() -> Optional[BridgeConnection]:
    """Return a connected bridge or None on failure.

    Used by editor_context for graceful fallback when the addon
    is not running.
    """
    try:
        return await get_bridge()
    except Exception:
        return None


async def close_bridge() -> None:
    """Disconnect and discard the shared bridge instance.

    Called in the server lifespan's finally block.
    """
    global _bridge, _bridge_lock

    if _bridge_lock is None:
        _bridge_lock = asyncio.Lock()

    async with _bridge_lock:
        if _bridge is not None:
            try:
                await _bridge.disconnect()
            except Exception:
                pass
            _bridge = None
