"""Status model <-> proto converters."""

from __future__ import annotations

from typing import TYPE_CHECKING

from radiens_core._converters._common_enums import port_from_proto, record_mode_from_proto, stream_mode_from_proto
from radiens_core.models.ports import GPIOChannelCount, PortChannelCount
from radiens_core.models.status import BackboneStatus, RecordingStatus, StreamingStatus

if TYPE_CHECKING:
    from radiens_core._generated import allegoserver_pb2, common_pb2


def streaming_status_from_proto(pb: allegoserver_pb2.StreamingStatus) -> StreamingStatus:
    """Convert proto StreamingStatus to domain StreamingStatus."""
    return StreamingStatus(
        stream_mode=stream_mode_from_proto(pb.streamMode),
        primary_cache_t_range=list(pb.primaryCacheTRange),
        hardware_memory_level=pb.hardwareMemoryLevel,
    )


def recording_status_from_proto(pb: allegoserver_pb2.RecordingStatus) -> RecordingStatus:
    """Convert proto RecordingStatus to domain RecordingStatus."""
    return RecordingStatus(
        record_mode=record_mode_from_proto(pb.recordMode),
        active_filename=pb.activeFileName,
        duration=pb.duration,
        error=pb.error,
        record_mode_port_a=record_mode_from_proto(pb.recordModePortA) if pb.HasField("recordModePortA") else None,
        record_mode_port_b=record_mode_from_proto(pb.recordModePortB) if pb.HasField("recordModePortB") else None,
        record_mode_port_c=record_mode_from_proto(pb.recordModePortC) if pb.HasField("recordModePortC") else None,
        record_mode_port_d=record_mode_from_proto(pb.recordModePortD) if pb.HasField("recordModePortD") else None,
        record_mode_port_e=record_mode_from_proto(pb.recordModePortE) if pb.HasField("recordModePortE") else None,
        record_mode_port_f=record_mode_from_proto(pb.recordModePortF) if pb.HasField("recordModePortF") else None,
        record_mode_port_g=record_mode_from_proto(pb.recordModePortG) if pb.HasField("recordModePortG") else None,
        record_mode_port_h=record_mode_from_proto(pb.recordModePortH) if pb.HasField("recordModePortH") else None,
    )


def port_channel_count_from_proto(pb: common_pb2.PortChannelCount) -> PortChannelCount:
    """Convert proto PortChannelCount to domain PortChannelCount."""
    return PortChannelCount(
        port=port_from_proto(pb.port),
        channel_count=pb.channelCount,
    )


def gpio_channel_count_from_proto(pb: common_pb2.GPIOChannelCount) -> GPIOChannelCount:
    """Convert proto GPIOChannelCount to domain GPIOChannelCount."""
    return GPIOChannelCount(
        n_aux=pb.nAux,
        n_din=pb.nDin,
        n_dout=pb.nDout,
    )


def backbone_status_from_proto(pb: allegoserver_pb2.BackboneStatus) -> BackboneStatus:
    """Convert proto BackboneStatus to domain BackboneStatus."""
    return BackboneStatus(
        streaming=streaming_status_from_proto(pb.streaming),
        recording=recording_status_from_proto(pb.recording),
        ports=[port_channel_count_from_proto(port) for port in pb.ports],
        is_connected=pb.isConnected,
        gpio_channel_count=gpio_channel_count_from_proto(pb.gpioChannelCount),
    )
