from __future__ import annotations

from dataclasses import dataclass


@dataclass(frozen=True)
class BusProtocol:
    raw_value: str
    description: str
    bitrate: int
    is_can: bool
    is_11bit: bool
    broadcast_header: int

    @classmethod
    def from_raw(cls, raw: str) -> "BusProtocol":
        raw_upper = raw.upper()
        return _PROTOCOLS.get(raw_upper, UNKNOWN)


UNKNOWN = BusProtocol(raw_value="?", description="Unknown", bitrate=-1, is_can=False, is_11bit=False, broadcast_header=0)
AUTO = BusProtocol(raw_value="0", description="Automatic", bitrate=-1, is_can=False, is_11bit=False, broadcast_header=0)
J1850_PWM = BusProtocol(raw_value="1", description="SAE J1850 PWM", bitrate=-1, is_can=False, is_11bit=False, broadcast_header=0)
J1850_VPW = BusProtocol(raw_value="2", description="SAE J1850 VPW", bitrate=-1, is_can=False, is_11bit=False, broadcast_header=0)
ISO_9141_2 = BusProtocol(raw_value="3", description="ISO 9141-2", bitrate=-1, is_can=False, is_11bit=False, broadcast_header=0)
ISO_14230_4_5B = BusProtocol(raw_value="4", description="ISO 14230-4 (KWP 5BAUD)", bitrate=-1, is_can=False, is_11bit=False, broadcast_header=0)
ISO_14230_4_FAST = BusProtocol(raw_value="5", description="ISO 14230-4 (KWP FAST)", bitrate=-1, is_can=False, is_11bit=False, broadcast_header=0)
CAN_11B_500K = BusProtocol(raw_value="6", description="ISO 15765-4 (CAN 11/500)", bitrate=500000, is_can=True, is_11bit=True, broadcast_header=0x7DF)
CAN_29B_500K = BusProtocol(raw_value="7", description="ISO 15765-4 (CAN 29/500)", bitrate=500000, is_can=True, is_11bit=False, broadcast_header=0x18DB33F1)
CAN_11B_250K = BusProtocol(raw_value="8", description="ISO 15765-4 (CAN 11/250)", bitrate=250000, is_can=True, is_11bit=True, broadcast_header=0x7DF)
CAN_29B_250K = BusProtocol(raw_value="9", description="ISO 15765-4 (CAN 29/250)", bitrate=250000, is_can=True, is_11bit=False, broadcast_header=0x18DB33F1)
USER1_11B_125K = BusProtocol(raw_value="B", description="User1 (CAN 11/125)", bitrate=125000, is_can=True, is_11bit=True, broadcast_header=0x7DF)
USER2_11B_50K = BusProtocol(raw_value="C", description="User2 (CAN 11/50)", bitrate=50000, is_can=True, is_11bit=True, broadcast_header=0x7DF)

_PROTOCOLS = {
    UNKNOWN.raw_value: UNKNOWN,
    AUTO.raw_value: AUTO,
    J1850_PWM.raw_value: J1850_PWM,
    J1850_VPW.raw_value: J1850_VPW,
    ISO_9141_2.raw_value: ISO_9141_2,
    ISO_14230_4_5B.raw_value: ISO_14230_4_5B,
    ISO_14230_4_FAST.raw_value: ISO_14230_4_FAST,
    CAN_11B_500K.raw_value: CAN_11B_500K,
    CAN_29B_500K.raw_value: CAN_29B_500K,
    CAN_11B_250K.raw_value: CAN_11B_250K,
    CAN_29B_250K.raw_value: CAN_29B_250K,
    USER1_11B_125K.raw_value: USER1_11B_125K,
    USER2_11B_50K.raw_value: USER2_11B_50K,
}

CAN_PROTOCOLS = {CAN_11B_250K, CAN_11B_500K, CAN_29B_250K, CAN_29B_500K, USER1_11B_125K, USER2_11B_50K}
