use crate::constants::SHB_UNSPECIFIED_LENGTH;

/// pcapng block types
#[derive(Debug, Hash, PartialEq, Eq)]
pub enum BlockType {
    SectionHeader,
    InterfaceDescription,
    SimplePacket,
    NameResolution,
    InterfaceStatistics,
    EnhancedPacket,
    Unknown(u32),
}

impl BlockType {
    pub fn value(&self) -> u32 {
        match self {
            Self::SectionHeader => 0x0A0D0D0A,
            Self::InterfaceDescription => 0x00000001,
            Self::SimplePacket => 0x00000003,
            Self::NameResolution => 0x00000004,
            Self::InterfaceStatistics => 0x00000005,
            Self::EnhancedPacket => 0x00000006,
            Self::Unknown(x) => *x,
        }
    }
}

pub enum SectionHeaderSectionLength {
    Unspecified,
    Bytes(u64),
}

impl SectionHeaderSectionLength {
    pub fn value(&self) -> u64 {
        match self {
            SectionHeaderSectionLength::Unspecified => SHB_UNSPECIFIED_LENGTH,
            SectionHeaderSectionLength::Bytes(n) => *n,
        }
    }
}

/// Link types as specified by <http://www.tcpdump.org/linktypes.html>.
pub enum LinkType {
    Null,
    Ethernet,
    Ax25,
    Ieee8025,
    ArcnetBsd,
    Slip,
    Ppp,
    Fddi,
    PppHdlc,
    PppEther,
    AtmRfc1483,
    Raw,
    CHdlc,
    Ieee80211,
    Frelay,
    Loop,
    LinuxSll,
    Ltalk,
    Pflog,
    Ieee80211Prism,
    IpOverFc,
    Sunatm,
    Ieee80211Radiotap,
    ArcnetLinux,
    AppleIpOverIeee1394,
    Mtp2WithPhdr,
    Mtp2,
    Mtp3,
    Sccp,
    Docsis,
    LinuxIrda,
    User0,
    User1,
    User2,
    User3,
    User4,
    User5,
    User6,
    User7,
    User8,
    User9,
    User10,
    User11,
    User12,
    User13,
    User14,
    User15,
    Ieee80211Avs,
    BacnetMsTp,
    PppPppd,
    GprsLlc,
    GpfT,
    GpfF,
    LinuxLapd,
    Mfr,
    BluetoothHciH4,
    UsbLinux,
    Ppi,
    Ieee802154Withfcs,
    Sita,
    Erf,
    BluetoothHciH4WithPhdr,
    Ax25Kiss,
    Lapd,
    PppWithDir,
    CHdlcWithDir,
    FrelayWithDir,
    LapbWithDir,
    IpmbLinux,
    Ieee802154NonaskPhy,
    UsbLinuxMmapped,
    Fc2,
    Fc2WithFrameDelims,
    Ipnet,
    CanSocketcan,
    Ipv4,
    Ipv6,
    Ieee802154Nofcs,
    Dbus,
    DvbCi,
    Mux27010,
    Stanag5066DPdu,
    Nflog,
    Netanalyzer,
    NetanalyzerTransparent,
    Ipoib,
    Mpeg2Ts,
    Ng40,
    NfcLlcp,
    Infiniband,
    Sctp,
    Usbpcap,
    RtacSerial,
    BluetoothLeLl,
    Netlink,
    BluetoothLinuxMonitor,
    BluetoothBredrBb,
    BluetoothLeLlWithPhdr,
    ProfibusDl,
    Pktap,
    Epon,
    IpmiHpm2,
    ZwaveR1R2,
    ZwaveR3,
    WattstopperDlm,
    Iso14443,
    Rds,
    UsbDarwin,
    Sdlc,
    Loratap,
    Vsock,
    NordicBle,
    Docsis31Xra31,
    EthernetMpacket,
    DisplayportAux,
    LinuxSll2,
    Openvizsla,
    Ebhscr,
    VppDispatch,
    DsaTagBrcm,
    DsaTagBrcmPrepend,
    Ieee802154Tap,
    DsaTagDsa,
    DsaTagEdsa,
    Elee,
    ZWaveSerial,
    Usb20,
    AtscAlp,
}

impl LinkType {
    pub fn value(&self) -> u16 {
        match self {
            Self::Null => 0,
            Self::Ethernet => 1,
            Self::Ax25 => 3,
            Self::Ieee8025 => 6,
            Self::ArcnetBsd => 7,
            Self::Slip => 8,
            Self::Ppp => 9,
            Self::Fddi => 10,
            Self::PppHdlc => 50,
            Self::PppEther => 51,
            Self::AtmRfc1483 => 100,
            Self::Raw => 101,
            Self::CHdlc => 104,
            Self::Ieee80211 => 105,
            Self::Frelay => 107,
            Self::Loop => 108,
            Self::LinuxSll => 113,
            Self::Ltalk => 114,
            Self::Pflog => 117,
            Self::Ieee80211Prism => 119,
            Self::IpOverFc => 122,
            Self::Sunatm => 123,
            Self::Ieee80211Radiotap => 127,
            Self::ArcnetLinux => 129,
            Self::AppleIpOverIeee1394 => 138,
            Self::Mtp2WithPhdr => 139,
            Self::Mtp2 => 140,
            Self::Mtp3 => 141,
            Self::Sccp => 142,
            Self::Docsis => 143,
            Self::LinuxIrda => 144,
            Self::User0 => 147,
            Self::User1 => 148,
            Self::User2 => 149,
            Self::User3 => 150,
            Self::User4 => 151,
            Self::User5 => 152,
            Self::User6 => 153,
            Self::User7 => 154,
            Self::User8 => 155,
            Self::User9 => 156,
            Self::User10 => 157,
            Self::User11 => 158,
            Self::User12 => 159,
            Self::User13 => 160,
            Self::User14 => 161,
            Self::User15 => 162,
            Self::Ieee80211Avs => 163,
            Self::BacnetMsTp => 165,
            Self::PppPppd => 166,
            Self::GprsLlc => 169,
            Self::GpfT => 170,
            Self::GpfF => 171,
            Self::LinuxLapd => 177,
            Self::Mfr => 182,
            Self::BluetoothHciH4 => 187,
            Self::UsbLinux => 189,
            Self::Ppi => 192,
            Self::Ieee802154Withfcs => 195,
            Self::Sita => 196,
            Self::Erf => 197,
            Self::BluetoothHciH4WithPhdr => 201,
            Self::Ax25Kiss => 202,
            Self::Lapd => 203,
            Self::PppWithDir => 204,
            Self::CHdlcWithDir => 205,
            Self::FrelayWithDir => 206,
            Self::LapbWithDir => 207,
            Self::IpmbLinux => 209,
            Self::Ieee802154NonaskPhy => 215,
            Self::UsbLinuxMmapped => 220,
            Self::Fc2 => 224,
            Self::Fc2WithFrameDelims => 225,
            Self::Ipnet => 226,
            Self::CanSocketcan => 227,
            Self::Ipv4 => 228,
            Self::Ipv6 => 229,
            Self::Ieee802154Nofcs => 230,
            Self::Dbus => 231,
            Self::DvbCi => 235,
            Self::Mux27010 => 236,
            Self::Stanag5066DPdu => 237,
            Self::Nflog => 239,
            Self::Netanalyzer => 240,
            Self::NetanalyzerTransparent => 241,
            Self::Ipoib => 242,
            Self::Mpeg2Ts => 243,
            Self::Ng40 => 244,
            Self::NfcLlcp => 245,
            Self::Infiniband => 247,
            Self::Sctp => 248,
            Self::Usbpcap => 249,
            Self::RtacSerial => 250,
            Self::BluetoothLeLl => 251,
            Self::Netlink => 253,
            Self::BluetoothLinuxMonitor => 254,
            Self::BluetoothBredrBb => 255,
            Self::BluetoothLeLlWithPhdr => 256,
            Self::ProfibusDl => 257,
            Self::Pktap => 258,
            Self::Epon => 259,
            Self::IpmiHpm2 => 260,
            Self::ZwaveR1R2 => 261,
            Self::ZwaveR3 => 262,
            Self::WattstopperDlm => 263,
            Self::Iso14443 => 264,
            Self::Rds => 265,
            Self::UsbDarwin => 266,
            Self::Sdlc => 268,
            Self::Loratap => 270,
            Self::Vsock => 271,
            Self::NordicBle => 272,
            Self::Docsis31Xra31 => 273,
            Self::EthernetMpacket => 274,
            Self::DisplayportAux => 275,
            Self::LinuxSll2 => 276,
            Self::Openvizsla => 278,
            Self::Ebhscr => 279,
            Self::VppDispatch => 280,
            Self::DsaTagBrcm => 281,
            Self::DsaTagBrcmPrepend => 282,
            Self::Ieee802154Tap => 283,
            Self::DsaTagDsa => 284,
            Self::DsaTagEdsa => 285,
            Self::Elee => 286,
            Self::ZWaveSerial => 287,
            Self::Usb20 => 288,
            Self::AtscAlp => 289,
        }
    }
}

pub enum PacketDirection {
    Unavailable,
    Inbound,
    Outbound,
}

impl PacketDirection {
    pub fn value(&self) -> u8 {
        match self {
            Self::Unavailable => 0,
            Self::Inbound => 1,
            Self::Outbound => 2,
        }
    }
}

pub enum ReceptionType {
    Unspecified,
    Unicast,
    Multicast,
    Broadcast,
    Promiscuous,
}

impl ReceptionType {
    pub fn value(&self) -> u8 {
        match self {
            Self::Unspecified => 0,
            Self::Unicast => 1,
            Self::Multicast => 2,
            Self::Broadcast => 3,
            Self::Promiscuous => 4,
        }
    }
}
