"""Domain enum <-> proto enum mappings.

This is the ONLY bridge between domain enums and proto enums.
Adding a proto enum value without updating these maps -> mypy error via exhaustive match.
"""

from __future__ import annotations

from radiens_core._generated import allegoserver_pb2, common_pb2
from radiens_core.models.enums import (
    BackboneMode,
    DataRecordingType,
    Port,
    RadiensFileType,
    RecordMode,
    SignalType,
    StimPolarity,
    StimPulseMode,
    StimShape,
    StimStep,
    StimTriggerEdgeOrLevel,
    StimTriggerHighOrLow,
    StreamMode,
    TriggerChannel,
    TrsMode,
)

# --- SignalType ---

_SIGNAL_TYPE_TO_PROTO: dict[SignalType, common_pb2.SignalType.ValueType] = {
    SignalType.AMP: common_pb2.PRI,
    SignalType.AIN: common_pb2.AUX,
    SignalType.DIN: common_pb2.DIN,
    SignalType.DOUT: common_pb2.DOUT,
}

_SIGNAL_TYPE_FROM_PROTO: dict[int, SignalType] = {
    int(common_pb2.PRI): SignalType.AMP,
    int(common_pb2.AUX): SignalType.AIN,
    int(common_pb2.DIN): SignalType.DIN,
    int(common_pb2.DOUT): SignalType.DOUT,
}


def signal_type_to_proto(st: SignalType) -> common_pb2.SignalType.ValueType:
    """Convert domain SignalType to proto SignalType."""
    return _SIGNAL_TYPE_TO_PROTO[st]


def signal_type_from_proto(pb: int) -> SignalType:
    """Convert proto SignalType int to domain SignalType."""
    return _SIGNAL_TYPE_FROM_PROTO[pb]


# --- TrsMode ---

_TRS_MODE_TO_PROTO: dict[TrsMode, common_pb2.TimeRangeSelMode.ValueType] = {
    TrsMode.SUBSET: common_pb2.TRS_SUBSET,
    TrsMode.TO_HEAD: common_pb2.TRS_TO_HEAD,
    TrsMode.FROM_HEAD: common_pb2.TRS_FROM_HEAD,
}

_TRS_MODE_FROM_PROTO: dict[int, TrsMode] = {
    int(common_pb2.TRS_SUBSET): TrsMode.SUBSET,
    int(common_pb2.TRS_TO_HEAD): TrsMode.TO_HEAD,
    int(common_pb2.TRS_FROM_HEAD): TrsMode.FROM_HEAD,
}


def trs_mode_to_proto(mode: TrsMode) -> common_pb2.TimeRangeSelMode.ValueType:
    """Convert domain TrsMode to proto TimeRangeSelMode."""
    return _TRS_MODE_TO_PROTO[mode]


def trs_mode_from_proto(pb: int) -> TrsMode:
    """Convert proto TimeRangeSelMode int to domain TrsMode."""
    return _TRS_MODE_FROM_PROTO[pb]


# --- RadiensFileType ---

_FILE_TYPE_FROM_PROTO: dict[int, RadiensFileType] = {
    int(common_pb2.RHD): RadiensFileType.RHD,
    int(common_pb2.XDAT): RadiensFileType.XDAT,
    int(common_pb2.CSV): RadiensFileType.CSV,
    int(common_pb2.HDF5): RadiensFileType.HDF5,
    int(common_pb2.NEX5): RadiensFileType.NEX5,
    int(common_pb2.NWB): RadiensFileType.NWB,
    int(common_pb2.KILOSORT2): RadiensFileType.KILOSORT2,
    int(common_pb2.NSX): RadiensFileType.NSX,
    int(common_pb2.TDT): RadiensFileType.TDT,
    int(common_pb2.SPIKES): RadiensFileType.SPIKES,
    int(common_pb2.OE_DAT): RadiensFileType.OE_DAT,
}


def file_type_from_proto(pb: int) -> RadiensFileType:
    """Convert proto RadixFileTypes int to domain RadiensFileType."""
    return _FILE_TYPE_FROM_PROTO[pb]


_FILE_TYPE_TO_PROTO: dict[RadiensFileType, common_pb2.RadixFileTypes.ValueType] = {
    RadiensFileType.RHD: common_pb2.RHD,
    RadiensFileType.XDAT: common_pb2.XDAT,
    RadiensFileType.CSV: common_pb2.CSV,
    RadiensFileType.HDF5: common_pb2.HDF5,
    RadiensFileType.NEX5: common_pb2.NEX5,
    RadiensFileType.NWB: common_pb2.NWB,
    RadiensFileType.KILOSORT2: common_pb2.KILOSORT2,
    RadiensFileType.NSX: common_pb2.NSX,
    RadiensFileType.TDT: common_pb2.TDT,
    RadiensFileType.SPIKES: common_pb2.SPIKES,
    RadiensFileType.OE_DAT: common_pb2.OE_DAT,
}


def file_type_to_proto(ft: RadiensFileType) -> common_pb2.RadixFileTypes.ValueType:
    """Convert domain RadiensFileType to proto RadixFileTypes."""
    return _FILE_TYPE_TO_PROTO[ft]


# --- StimShape ---

_STIM_SHAPE_TO_PROTO: dict[StimShape, allegoserver_pb2.StimShape.ValueType] = {
    StimShape.BIPHASIC: allegoserver_pb2.BIPHASIC,
    StimShape.BIPHASIC_INTERPHASE_DELAY: allegoserver_pb2.BIPHASIC_INTERPHASE_DELAY,
    StimShape.TRIPHASIC: allegoserver_pb2.TRIPHASIC,
    StimShape.MONOPHASIC: allegoserver_pb2.MONOPHASIC,
}

_STIM_SHAPE_FROM_PROTO: dict[int, StimShape] = {
    int(allegoserver_pb2.BIPHASIC): StimShape.BIPHASIC,
    int(allegoserver_pb2.BIPHASIC_INTERPHASE_DELAY): StimShape.BIPHASIC_INTERPHASE_DELAY,
    int(allegoserver_pb2.TRIPHASIC): StimShape.TRIPHASIC,
    int(allegoserver_pb2.MONOPHASIC): StimShape.MONOPHASIC,
}


def stim_shape_to_proto(ss: StimShape) -> allegoserver_pb2.StimShape.ValueType:
    """Convert domain StimShape to proto StimShape."""
    return _STIM_SHAPE_TO_PROTO[ss]


def stim_shape_from_proto(pb: int) -> StimShape:
    """Convert proto StimShape int to domain StimShape."""
    return _STIM_SHAPE_FROM_PROTO[pb]


# --- StimPolarity ---

_STIM_POLARITY_TO_PROTO: dict[StimPolarity, allegoserver_pb2.StimPolarity.ValueType] = {
    StimPolarity.CATHODIC_FIRST: allegoserver_pb2.CATHODIC_FIRST,
    StimPolarity.ANODIC_FIRST: allegoserver_pb2.ANODIC_FIRST,
}

_STIM_POLARITY_FROM_PROTO: dict[int, StimPolarity] = {
    int(allegoserver_pb2.CATHODIC_FIRST): StimPolarity.CATHODIC_FIRST,
    int(allegoserver_pb2.ANODIC_FIRST): StimPolarity.ANODIC_FIRST,
}


def stim_polarity_to_proto(sp: StimPolarity) -> allegoserver_pb2.StimPolarity.ValueType:
    """Convert domain StimPolarity to proto StimPolarity."""
    return _STIM_POLARITY_TO_PROTO[sp]


def stim_polarity_from_proto(pb: int) -> StimPolarity:
    """Convert proto StimPolarity int to domain StimPolarity."""
    return _STIM_POLARITY_FROM_PROTO[pb]


# --- StimTriggerEdgeOrLevel ---

_STIM_TRIGGER_EDGE_OR_LEVEL_TO_PROTO: dict[
    StimTriggerEdgeOrLevel, allegoserver_pb2.StimTriggerEdgeOrLevel.ValueType
] = {
    StimTriggerEdgeOrLevel.EDGE: allegoserver_pb2.ST_EDGE,
    StimTriggerEdgeOrLevel.LEVEL: allegoserver_pb2.ST_LEVEL,
}

_STIM_TRIGGER_EDGE_OR_LEVEL_FROM_PROTO: dict[int, StimTriggerEdgeOrLevel] = {
    int(allegoserver_pb2.ST_EDGE): StimTriggerEdgeOrLevel.EDGE,
    int(allegoserver_pb2.ST_LEVEL): StimTriggerEdgeOrLevel.LEVEL,
}


def stim_trigger_edge_or_level_to_proto(
    ste: StimTriggerEdgeOrLevel,
) -> allegoserver_pb2.StimTriggerEdgeOrLevel.ValueType:
    """Convert domain StimTriggerEdgeOrLevel to proto StimTriggerEdgeOrLevel."""
    return _STIM_TRIGGER_EDGE_OR_LEVEL_TO_PROTO[ste]


def stim_trigger_edge_or_level_from_proto(pb: int) -> StimTriggerEdgeOrLevel:
    """Convert proto StimTriggerEdgeOrLevel int to domain StimTriggerEdgeOrLevel."""
    return _STIM_TRIGGER_EDGE_OR_LEVEL_FROM_PROTO[pb]


# --- StimTriggerHighOrLow ---

_STIM_TRIGGER_HIGH_OR_LOW_TO_PROTO: dict[StimTriggerHighOrLow, allegoserver_pb2.StimTriggerHighOrLow.ValueType] = {
    StimTriggerHighOrLow.HIGH: allegoserver_pb2.ST_HIGH,
    StimTriggerHighOrLow.LOW: allegoserver_pb2.ST_LOW,
}

_STIM_TRIGGER_HIGH_OR_LOW_FROM_PROTO: dict[int, StimTriggerHighOrLow] = {
    int(allegoserver_pb2.ST_HIGH): StimTriggerHighOrLow.HIGH,
    int(allegoserver_pb2.ST_LOW): StimTriggerHighOrLow.LOW,
}


def stim_trigger_level_to_proto(
    stl: StimTriggerHighOrLow,
) -> allegoserver_pb2.StimTriggerHighOrLow.ValueType:
    """Convert domain StimTriggerLevel to proto StimTriggerHighOrLow."""
    return _STIM_TRIGGER_HIGH_OR_LOW_TO_PROTO[stl]


def stim_trigger_level_from_proto(pb: int) -> StimTriggerHighOrLow:
    """Convert proto StimTriggerHighOrLow int to domain StimTriggerLevel."""
    return _STIM_TRIGGER_HIGH_OR_LOW_FROM_PROTO[pb]


# --- StimPulseMode ---

_STIM_PULSE_MODE_TO_PROTO: dict[StimPulseMode, allegoserver_pb2.StimPulseOrTrain.ValueType] = {
    StimPulseMode.SINGLE_PULSE: allegoserver_pb2.SINGLE_PULSE,
    StimPulseMode.PULSE_TRAIN: allegoserver_pb2.PULSE_TRAIN,
}

_STIM_PULSE_MODE_FROM_PROTO: dict[int, StimPulseMode] = {
    int(allegoserver_pb2.SINGLE_PULSE): StimPulseMode.SINGLE_PULSE,
    int(allegoserver_pb2.PULSE_TRAIN): StimPulseMode.PULSE_TRAIN,
}


def stim_pulse_mode_to_proto(
    spm: StimPulseMode,
) -> allegoserver_pb2.StimPulseOrTrain.ValueType:
    """Convert domain StimPulseMode to proto StimPulseOrTrain."""
    return _STIM_PULSE_MODE_TO_PROTO[spm]


def stim_pulse_mode_from_proto(pb: int) -> StimPulseMode:
    """Convert proto StimPulseOrTrain int to domain StimPulseMode."""
    return _STIM_PULSE_MODE_FROM_PROTO[pb]


# --- StreamMode ---

_STREAM_MODE_TO_PROTO: dict[StreamMode, allegoserver_pb2.StreamMode.ValueType] = {
    StreamMode.OFF: allegoserver_pb2.S_OFF,
    StreamMode.ON: allegoserver_pb2.S_ON,
}

_STREAM_MODE_FROM_PROTO: dict[int, StreamMode] = {
    int(allegoserver_pb2.S_OFF): StreamMode.OFF,
    int(allegoserver_pb2.S_ON): StreamMode.ON,
}


def stream_mode_to_proto(sm: StreamMode) -> allegoserver_pb2.StreamMode.ValueType:
    """Convert domain StreamMode to proto StreamMode."""
    return _STREAM_MODE_TO_PROTO[sm]


def stream_mode_from_proto(pb: int) -> StreamMode:
    """Convert proto StreamMode int to domain StreamMode."""
    return _STREAM_MODE_FROM_PROTO[pb]


# --- RecordMode ---

_RECORD_MODE_TO_PROTO: dict[RecordMode, allegoserver_pb2.RecordMode.ValueType] = {
    RecordMode.OFF: allegoserver_pb2.R_OFF,
    RecordMode.ON: allegoserver_pb2.R_ON,
}

_RECORD_MODE_FROM_PROTO: dict[int, RecordMode] = {
    int(allegoserver_pb2.R_OFF): RecordMode.OFF,
    int(allegoserver_pb2.R_ON): RecordMode.ON,
}


def record_mode_to_proto(rm: RecordMode) -> allegoserver_pb2.RecordMode.ValueType:
    """Convert domain RecordMode to proto RecordMode."""
    return _RECORD_MODE_TO_PROTO[rm]


def record_mode_from_proto(pb: int) -> RecordMode:
    """Convert proto RecordMode int to domain RecordMode."""
    return _RECORD_MODE_FROM_PROTO[pb]


# --- Port ---

_PORT_TO_PROTO: dict[Port, common_pb2.Port.ValueType] = {
    Port.A: common_pb2.A,
    Port.B: common_pb2.B,
    Port.C: common_pb2.C,
    Port.D: common_pb2.D,
    Port.E: common_pb2.E,
    Port.F: common_pb2.F,
    Port.G: common_pb2.G,
    Port.H: common_pb2.H,
}

_PORT_FROM_PROTO: dict[int, Port] = {
    int(common_pb2.A): Port.A,
    int(common_pb2.B): Port.B,
    int(common_pb2.C): Port.C,
    int(common_pb2.D): Port.D,
    int(common_pb2.E): Port.E,
    int(common_pb2.F): Port.F,
    int(common_pb2.G): Port.G,
    int(common_pb2.H): Port.H,
}


def port_to_proto(port: Port) -> common_pb2.Port.ValueType:
    """Convert domain Port to proto Port."""
    return _PORT_TO_PROTO[port]


def port_from_proto(pb: int) -> Port:
    """Convert proto Port int to domain Port."""
    return _PORT_FROM_PROTO[pb]


# --- BackboneMode ---

_BACKBONE_MODE_TO_PROTO: dict[BackboneMode, allegoserver_pb2.BackboneMode.ValueType] = {
    BackboneMode.SMARTBOX_PRO: allegoserver_pb2.SMARTBOX_PRO,
    BackboneMode.SMARTBOX_SIM_GEN_SINE: allegoserver_pb2.SMARTBOX_SIM_GEN_SINE,
    BackboneMode.SMARTBOX_SIM_GEN_SPIKES: allegoserver_pb2.SMARTBOX_SIM_GEN_SPIKES,
    BackboneMode.SMARTBOX_SIM_DATASOURCE: allegoserver_pb2.SMARTBOX_SIM_DATASOURCE,
    BackboneMode.OPEN_EPHYS_USB3: allegoserver_pb2.OPEN_EPHYS_USB3,
    BackboneMode.INTAN_RECORDING_CONTROLLER_1024: allegoserver_pb2.INTAN_RECORDING_CONTROLLER_1024,
    BackboneMode.SMARTBOX_CLASSIC: allegoserver_pb2.SMARTBOX_CLASSIC,
    BackboneMode.INTAN_RECORDING_CONTROLLER_512: allegoserver_pb2.INTAN_RECORDING_CONTROLLER_512,
    BackboneMode.OPEN_EPHYS_USB2: allegoserver_pb2.OPEN_EPHYS_USB2,
    BackboneMode.INTAN_USB2: allegoserver_pb2.INTAN_USB2,
    BackboneMode.SMARTBOX_SIM_GEN_SINE_MAPPED: allegoserver_pb2.SMARTBOX_SIM_GEN_SINE_MAPPED,
    BackboneMode.SMARTBOX_SIM_GEN_SINE_HIGH_FREQ: allegoserver_pb2.SMARTBOX_SIM_GEN_SINE_HIGH_FREQ,
    BackboneMode.SMARTBOX_SIM_GEN_SINE_MULTI_BAND: allegoserver_pb2.SMARTBOX_SIM_GEN_SINE_MULTI_BAND,
    BackboneMode.SMARTBOX_PRO_SINAPS_256: allegoserver_pb2.SMARTBOX_PRO_SINAPS_256,
    BackboneMode.SMARTBOX_PRO_SINAPS_1024: allegoserver_pb2.SMARTBOX_PRO_SINAPS_1024,
    BackboneMode.XDAQ_ONE_REC: allegoserver_pb2.XDAQ_ONE_REC,
    BackboneMode.XDAQ_ONE_STIM: allegoserver_pb2.XDAQ_ONE_STIM,
    BackboneMode.XDAQ_CORE_REC: allegoserver_pb2.XDAQ_CORE_REC,
    BackboneMode.XDAQ_CORE_STIM: allegoserver_pb2.XDAQ_CORE_STIM,
    BackboneMode.SMARTBOX_PRO_SINAPS_512: allegoserver_pb2.SMARTBOX_PRO_SINAPS_512,
    BackboneMode.XDAQ_GEN2_ONE_STIM: allegoserver_pb2.XDAQ_GEN2_ONE_STIM,
    BackboneMode.XDAQ_GEN2_CORE_STIM: allegoserver_pb2.XDAQ_GEN2_CORE_STIM,
    BackboneMode.XDAQ_GEN2_ONE_REC: allegoserver_pb2.XDAQ_GEN2_ONE_REC,
    BackboneMode.XDAQ_GEN2_CORE_REC: allegoserver_pb2.XDAQ_GEN2_CORE_REC,
    BackboneMode.SMARTBOX_SIM_GEN_LFP: allegoserver_pb2.SMARTBOX_SIM_GEN_LFP,
}

_BACKBONE_MODE_FROM_PROTO: dict[int, BackboneMode] = {
    int(allegoserver_pb2.SMARTBOX_PRO): BackboneMode.SMARTBOX_PRO,
    int(allegoserver_pb2.SMARTBOX_SIM_GEN_SINE): BackboneMode.SMARTBOX_SIM_GEN_SINE,
    int(allegoserver_pb2.SMARTBOX_SIM_GEN_SPIKES): BackboneMode.SMARTBOX_SIM_GEN_SPIKES,
    int(allegoserver_pb2.SMARTBOX_SIM_DATASOURCE): BackboneMode.SMARTBOX_SIM_DATASOURCE,
    int(allegoserver_pb2.OPEN_EPHYS_USB3): BackboneMode.OPEN_EPHYS_USB3,
    int(allegoserver_pb2.INTAN_RECORDING_CONTROLLER_1024): BackboneMode.INTAN_RECORDING_CONTROLLER_1024,
    int(allegoserver_pb2.SMARTBOX_CLASSIC): BackboneMode.SMARTBOX_CLASSIC,
    int(allegoserver_pb2.INTAN_RECORDING_CONTROLLER_512): BackboneMode.INTAN_RECORDING_CONTROLLER_512,
    int(allegoserver_pb2.OPEN_EPHYS_USB2): BackboneMode.OPEN_EPHYS_USB2,
    int(allegoserver_pb2.INTAN_USB2): BackboneMode.INTAN_USB2,
    int(allegoserver_pb2.SMARTBOX_SIM_GEN_SINE_MAPPED): BackboneMode.SMARTBOX_SIM_GEN_SINE_MAPPED,
    int(allegoserver_pb2.SMARTBOX_SIM_GEN_SINE_HIGH_FREQ): BackboneMode.SMARTBOX_SIM_GEN_SINE_HIGH_FREQ,
    int(allegoserver_pb2.SMARTBOX_SIM_GEN_SINE_MULTI_BAND): BackboneMode.SMARTBOX_SIM_GEN_SINE_MULTI_BAND,
    int(allegoserver_pb2.SMARTBOX_PRO_SINAPS_256): BackboneMode.SMARTBOX_PRO_SINAPS_256,
    int(allegoserver_pb2.SMARTBOX_PRO_SINAPS_1024): BackboneMode.SMARTBOX_PRO_SINAPS_1024,
    int(allegoserver_pb2.XDAQ_ONE_REC): BackboneMode.XDAQ_ONE_REC,
    int(allegoserver_pb2.XDAQ_ONE_STIM): BackboneMode.XDAQ_ONE_STIM,
    int(allegoserver_pb2.XDAQ_CORE_REC): BackboneMode.XDAQ_CORE_REC,
    int(allegoserver_pb2.XDAQ_CORE_STIM): BackboneMode.XDAQ_CORE_STIM,
    int(allegoserver_pb2.SMARTBOX_PRO_SINAPS_512): BackboneMode.SMARTBOX_PRO_SINAPS_512,
    int(allegoserver_pb2.XDAQ_GEN2_ONE_STIM): BackboneMode.XDAQ_GEN2_ONE_STIM,
    int(allegoserver_pb2.XDAQ_GEN2_CORE_STIM): BackboneMode.XDAQ_GEN2_CORE_STIM,
    int(allegoserver_pb2.XDAQ_GEN2_ONE_REC): BackboneMode.XDAQ_GEN2_ONE_REC,
    int(allegoserver_pb2.XDAQ_GEN2_CORE_REC): BackboneMode.XDAQ_GEN2_CORE_REC,
    int(allegoserver_pb2.SMARTBOX_SIM_GEN_LFP): BackboneMode.SMARTBOX_SIM_GEN_LFP,
}


def backbone_mode_to_proto(bm: BackboneMode) -> allegoserver_pb2.BackboneMode.ValueType:
    """Convert domain BackboneMode to proto BackboneMode."""
    return _BACKBONE_MODE_TO_PROTO[bm]


def backbone_mode_from_proto(pb: int) -> BackboneMode:
    """Convert proto BackboneMode int to domain BackboneMode."""
    return _BACKBONE_MODE_FROM_PROTO[pb]


# --- TriggerChannel ---

_TRIGGER_CHANNEL_TO_PROTO: dict[TriggerChannel, allegoserver_pb2.TriggerChannel.ValueType] = {
    TriggerChannel.T_DIN_0: allegoserver_pb2.T_DIN_0,
    TriggerChannel.T_DIN_1: allegoserver_pb2.T_DIN_1,
    TriggerChannel.T_DIN_2: allegoserver_pb2.T_DIN_2,
    TriggerChannel.T_DIN_3: allegoserver_pb2.T_DIN_3,
    TriggerChannel.T_DIN_4: allegoserver_pb2.T_DIN_4,
    TriggerChannel.T_DIN_5: allegoserver_pb2.T_DIN_5,
    TriggerChannel.T_DIN_6: allegoserver_pb2.T_DIN_6,
    TriggerChannel.T_DIN_7: allegoserver_pb2.T_DIN_7,
    TriggerChannel.T_DIN_8: allegoserver_pb2.T_DIN_8,
    TriggerChannel.T_DIN_9: allegoserver_pb2.T_DIN_9,
    TriggerChannel.T_DIN_10: allegoserver_pb2.T_DIN_10,
    TriggerChannel.T_DIN_11: allegoserver_pb2.T_DIN_11,
    TriggerChannel.T_DIN_12: allegoserver_pb2.T_DIN_12,
    TriggerChannel.T_DIN_13: allegoserver_pb2.T_DIN_13,
    TriggerChannel.T_DIN_14: allegoserver_pb2.T_DIN_14,
    TriggerChannel.T_DIN_15: allegoserver_pb2.T_DIN_15,
    TriggerChannel.T_DOUT_0: allegoserver_pb2.T_DOUT_0,
    TriggerChannel.T_DOUT_1: allegoserver_pb2.T_DOUT_1,
    TriggerChannel.T_DOUT_2: allegoserver_pb2.T_DOUT_2,
    TriggerChannel.T_DOUT_3: allegoserver_pb2.T_DOUT_3,
    TriggerChannel.T_DOUT_4: allegoserver_pb2.T_DOUT_4,
    TriggerChannel.T_DOUT_5: allegoserver_pb2.T_DOUT_5,
    TriggerChannel.T_DOUT_6: allegoserver_pb2.T_DOUT_6,
    TriggerChannel.T_DOUT_7: allegoserver_pb2.T_DOUT_7,
    TriggerChannel.T_DOUT_8: allegoserver_pb2.T_DOUT_8,
    TriggerChannel.T_DOUT_9: allegoserver_pb2.T_DOUT_9,
    TriggerChannel.T_DOUT_10: allegoserver_pb2.T_DOUT_10,
    TriggerChannel.T_DOUT_11: allegoserver_pb2.T_DOUT_11,
    TriggerChannel.T_DOUT_12: allegoserver_pb2.T_DOUT_12,
    TriggerChannel.T_DOUT_13: allegoserver_pb2.T_DOUT_13,
    TriggerChannel.T_DOUT_14: allegoserver_pb2.T_DOUT_14,
    TriggerChannel.T_DOUT_15: allegoserver_pb2.T_DOUT_15,
    TriggerChannel.T_NONE: allegoserver_pb2.T_NONE,
}

_TRIGGER_CHANNEL_FROM_PROTO: dict[int, TriggerChannel] = {
    int(allegoserver_pb2.T_DIN_0): TriggerChannel.T_DIN_0,
    int(allegoserver_pb2.T_DIN_1): TriggerChannel.T_DIN_1,
    int(allegoserver_pb2.T_DIN_2): TriggerChannel.T_DIN_2,
    int(allegoserver_pb2.T_DIN_3): TriggerChannel.T_DIN_3,
    int(allegoserver_pb2.T_DIN_4): TriggerChannel.T_DIN_4,
    int(allegoserver_pb2.T_DIN_5): TriggerChannel.T_DIN_5,
    int(allegoserver_pb2.T_DIN_6): TriggerChannel.T_DIN_6,
    int(allegoserver_pb2.T_DIN_7): TriggerChannel.T_DIN_7,
    int(allegoserver_pb2.T_DIN_8): TriggerChannel.T_DIN_8,
    int(allegoserver_pb2.T_DIN_9): TriggerChannel.T_DIN_9,
    int(allegoserver_pb2.T_DIN_10): TriggerChannel.T_DIN_10,
    int(allegoserver_pb2.T_DIN_11): TriggerChannel.T_DIN_11,
    int(allegoserver_pb2.T_DIN_12): TriggerChannel.T_DIN_12,
    int(allegoserver_pb2.T_DIN_13): TriggerChannel.T_DIN_13,
    int(allegoserver_pb2.T_DIN_14): TriggerChannel.T_DIN_14,
    int(allegoserver_pb2.T_DIN_15): TriggerChannel.T_DIN_15,
    int(allegoserver_pb2.T_DOUT_0): TriggerChannel.T_DOUT_0,
    int(allegoserver_pb2.T_DOUT_1): TriggerChannel.T_DOUT_1,
    int(allegoserver_pb2.T_DOUT_2): TriggerChannel.T_DOUT_2,
    int(allegoserver_pb2.T_DOUT_3): TriggerChannel.T_DOUT_3,
    int(allegoserver_pb2.T_DOUT_4): TriggerChannel.T_DOUT_4,
    int(allegoserver_pb2.T_DOUT_5): TriggerChannel.T_DOUT_5,
    int(allegoserver_pb2.T_DOUT_6): TriggerChannel.T_DOUT_6,
    int(allegoserver_pb2.T_DOUT_7): TriggerChannel.T_DOUT_7,
    int(allegoserver_pb2.T_DOUT_8): TriggerChannel.T_DOUT_8,
    int(allegoserver_pb2.T_DOUT_9): TriggerChannel.T_DOUT_9,
    int(allegoserver_pb2.T_DOUT_10): TriggerChannel.T_DOUT_10,
    int(allegoserver_pb2.T_DOUT_11): TriggerChannel.T_DOUT_11,
    int(allegoserver_pb2.T_DOUT_12): TriggerChannel.T_DOUT_12,
    int(allegoserver_pb2.T_DOUT_13): TriggerChannel.T_DOUT_13,
    int(allegoserver_pb2.T_DOUT_14): TriggerChannel.T_DOUT_14,
    int(allegoserver_pb2.T_DOUT_15): TriggerChannel.T_DOUT_15,
    int(allegoserver_pb2.T_NONE): TriggerChannel.T_NONE,
}


def trigger_channel_to_proto(tc: TriggerChannel) -> allegoserver_pb2.TriggerChannel.ValueType:
    """Convert domain TriggerChannel to proto TriggerChannel."""
    return _TRIGGER_CHANNEL_TO_PROTO[tc]


def trigger_channel_from_proto(pb: int) -> TriggerChannel:
    """Convert proto TriggerChannel int to domain TriggerChannel."""
    return _TRIGGER_CHANNEL_FROM_PROTO[pb]


# --- StimStep ---

_STIM_STEP_TO_PROTO: dict[StimStep, allegoserver_pb2.StimStep.ValueType] = {
    StimStep.STIM_STEP_SIZE_MIN: allegoserver_pb2.StimStepSizeMin,
    StimStep.STIM_STEP_SIZE_10_NA: allegoserver_pb2.StimStepSize10nA,
    StimStep.STIM_STEP_SIZE_20_NA: allegoserver_pb2.StimStepSize20nA,
    StimStep.STIM_STEP_SIZE_50_NA: allegoserver_pb2.StimStepSize50nA,
    StimStep.STIM_STEP_SIZE_100_NA: allegoserver_pb2.StimStepSize100nA,
    StimStep.STIM_STEP_SIZE_200_NA: allegoserver_pb2.StimStepSize200nA,
    StimStep.STIM_STEP_SIZE_500_NA: allegoserver_pb2.StimStepSize500nA,
    StimStep.STIM_STEP_SIZE_1_UA: allegoserver_pb2.StimStepSize1uA,
    StimStep.STIM_STEP_SIZE_2_UA: allegoserver_pb2.StimStepSize2uA,
    StimStep.STIM_STEP_SIZE_5_UA: allegoserver_pb2.StimStepSize5uA,
    StimStep.STIM_STEP_SIZE_10_UA: allegoserver_pb2.StimStepSize10uA,
    StimStep.STIM_STEP_SIZE_MAX: allegoserver_pb2.StimStepSizeMax,
}

_STIM_STEP_FROM_PROTO: dict[int, StimStep] = {
    int(allegoserver_pb2.StimStepSizeMin): StimStep.STIM_STEP_SIZE_MIN,
    int(allegoserver_pb2.StimStepSize10nA): StimStep.STIM_STEP_SIZE_10_NA,
    int(allegoserver_pb2.StimStepSize20nA): StimStep.STIM_STEP_SIZE_20_NA,
    int(allegoserver_pb2.StimStepSize50nA): StimStep.STIM_STEP_SIZE_50_NA,
    int(allegoserver_pb2.StimStepSize100nA): StimStep.STIM_STEP_SIZE_100_NA,
    int(allegoserver_pb2.StimStepSize200nA): StimStep.STIM_STEP_SIZE_200_NA,
    int(allegoserver_pb2.StimStepSize500nA): StimStep.STIM_STEP_SIZE_500_NA,
    int(allegoserver_pb2.StimStepSize1uA): StimStep.STIM_STEP_SIZE_1_UA,
    int(allegoserver_pb2.StimStepSize2uA): StimStep.STIM_STEP_SIZE_2_UA,
    int(allegoserver_pb2.StimStepSize5uA): StimStep.STIM_STEP_SIZE_5_UA,
    int(allegoserver_pb2.StimStepSize10uA): StimStep.STIM_STEP_SIZE_10_UA,
    int(allegoserver_pb2.StimStepSizeMax): StimStep.STIM_STEP_SIZE_MAX,
}


def stim_step_to_proto(ss: StimStep) -> allegoserver_pb2.StimStep.ValueType:
    """Convert domain StimStep to proto StimStep."""
    return _STIM_STEP_TO_PROTO[ss]


def stim_step_from_proto(pb: int) -> StimStep:
    """Convert proto StimStep int to domain StimStep."""
    return _STIM_STEP_FROM_PROTO[pb]


# --- DataRecordingType ---

_DATA_RECORDING_TYPE_TO_PROTO: dict[DataRecordingType, allegoserver_pb2.DataRecordingType.ValueType] = {
    DataRecordingType.CONTINUOUS: allegoserver_pb2.continuous,
    DataRecordingType.SPIKES: allegoserver_pb2.spikes,
    DataRecordingType.CONTINUOUS_AND_SPIKES: allegoserver_pb2.continuousAndSpikes,
}

_DATA_RECORDING_TYPE_FROM_PROTO: dict[int, DataRecordingType] = {
    int(allegoserver_pb2.continuous): DataRecordingType.CONTINUOUS,
    int(allegoserver_pb2.spikes): DataRecordingType.SPIKES,
    int(allegoserver_pb2.continuousAndSpikes): DataRecordingType.CONTINUOUS_AND_SPIKES,
}


def data_recording_type_to_proto(drt: DataRecordingType) -> allegoserver_pb2.DataRecordingType.ValueType:
    """Convert domain DataRecordingType to proto DataRecordingType."""
    return _DATA_RECORDING_TYPE_TO_PROTO[drt]


def data_recording_type_from_proto(pb: int) -> DataRecordingType:
    """Convert proto DataRecordingType int to domain DataRecordingType."""
    return _DATA_RECORDING_TYPE_FROM_PROTO[pb]
