"""Transport and adapter management."""

import logging

from fastmcp import Context
from fastmcp.contrib.mcp_mixin import MCPMixin, mcp_tool

from mcjtag.mixins.helpers import require_session
from mcjtag.models import AdapterSpeedResult, TransportInfo
from mcjtag.state import SessionState

log = logging.getLogger(__name__)


def _get_state(ctx: Context) -> SessionState:
    return ctx.request_context.lifespan_context


class TransportMixin(MCPMixin):
    """Tools for querying and configuring the debug transport and adapter."""

    @mcp_tool()
    async def transport_info(self, ctx: Context) -> TransportInfo:
        """Get the active debug transport, adapter name, speed, and available transports.

        Returns the current transport (jtag/swd/swim), the adapter
        interface (cmsis-dap, stlink, jlink, etc.), the clock speed in
        kHz, and the list of transports the adapter supports.
        """
        state = _get_state(ctx)
        require_session(state)

        transport = state.session.transport
        current = await transport.select()
        available = await transport.list()
        adapter = await transport.adapter_info()

        speed = None
        try:
            speed = await transport.adapter_speed()
        except Exception:
            log.debug("Could not read adapter speed", exc_info=True)

        return TransportInfo(
            transport=current,
            adapter=adapter,
            speed_khz=speed,
            available_transports=available,
        )

    @mcp_tool()
    async def adapter_speed(self, ctx: Context, khz: int | None = None) -> AdapterSpeedResult:
        """Get or set the debug adapter clock speed.

        Faster speeds reduce transfer time but may cause communication
        errors on long cables or noisy connections. Typical values:
        - 100-1000 kHz: conservative / initial connection
        - 1000-4000 kHz: normal operation (SWD)
        - 4000-24000 kHz: high-speed (good wiring required)

        Args:
            khz: Speed in kHz. If omitted, returns the current speed.
        """
        state = _get_state(ctx)
        require_session(state)

        changed = khz is not None
        speed = await state.session.transport.adapter_speed(khz)
        return AdapterSpeedResult(speed_khz=speed, changed=changed)
