// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use {
    failure::Fail,
    fuchsia_syslog::fx_log_warn,
    fuchsia_zircon as zx,
    std::{
        fmt,
        io::{Cursor, Write},
        result,
    },
};

/// Result type for AVDTP, using avdtp::Error
pub type Result<T> = result::Result<T, Error>;

/// The error type of the AVDTP library.
#[derive(Fail, Debug, PartialEq)]
pub enum Error {
    /// The value that was sent on the wire was out of range.
    #[fail(display = "Value was out of range")]
    OutOfRange,

    /// The signal identifier was invalid when parsing a message.
    #[fail(display = "Invalid signal id for {:?}: {:X?}", _0, _1)]
    InvalidSignalId(TxLabel, u8),

    /// The header was invalid when parsing a message from the peer.
    #[fail(display = "Invalid Header for a AVDTP message")]
    InvalidHeader,

    /// The body format was invalid when parsing a message from the peer.
    #[fail(display = "Failed to parse AVDTP message contents")]
    InvalidMessage,

    /// The remote end failed to respond to this command in time.
    #[fail(display = "Command timed out")]
    Timeout,

    /// The Remote end rejected a command we sent (with this error code)
    #[fail(display = "Remote end rejected the command (code = {:}", _0)]
    RemoteRejected(u8),

    /// The Remote end rejected a set configuration or reconfigure command we sent,
    /// indicating this ServiceCategory (code).
    /// The indicated ServiceCategory can be retrieved using `ServiceCategory::try_from`
    #[fail(
        display = "Remote end rejected the command (Category = {:}, code = {:}",
        _0, _1
    )]
    RemoteConfigRejected(u8, u8),

    /// The Remote end rejected a start or suspend command we sent, indicating this SEID and error
    /// code.
    #[fail(
        display = "Remote end rejected the command (SEID = {:}, code = {:}",
        _0, _1
    )]
    RemoteStreamRejected(u8, u8),

    /// When a message hasn't been implemented yet, the parser will return this.
    #[fail(display = "Message has not been implemented yet")]
    UnimplementedMessage,

    /// The distant peer has disconnected.
    #[fail(display = "Peer has disconnected")]
    PeerDisconnected,

    /// Sent if a Command Future is polled after it's already completed
    #[fail(display = "Command Response has already been received")]
    AlreadyReceived,

    /// Encountered an IO error setting up the channel
    #[fail(display = "Encountered an IO error reading from the peer: {}", _0)]
    ChannelSetup(#[cause] zx::Status),

    /// Encountered an IO error reading from the peer.
    #[fail(display = "Encountered an IO error reading from the peer: {}", _0)]
    PeerRead(#[cause] zx::Status),

    /// Encountered an IO error reading from the peer.
    #[fail(display = "Encountered an IO error writing to the peer: {}", _0)]
    PeerWrite(#[cause] zx::Status),

    /// A message couldn't be encoded.
    #[fail(display = "Encontered an error encoding a message")]
    Encoding,

    /// An error has been detected, and the request that is being handled
    /// should be rejected with the error code given.
    #[fail(display = "Invalid request detected: {:?}", _0)]
    RequestInvalid(ErrorCode),

    /// Same as RequestInvalid, but an extra byte is included, which is used
    /// in Stream and Configure responses
    #[fail(display = "Invalid request detected: {:?} (extra: {:?})", _0, _1)]
    RequestInvalidExtra(ErrorCode, u8),

    /// An operation was attempted in an Invalid State
    #[fail(display = "Invalid State")]
    InvalidState,

    #[doc(hidden)]
    #[fail(display = "__Nonexhaustive error should never be created.")]
    __Nonexhaustive,
}

/// Generates an enum value where each variant can be converted into a constant in the given
/// raw_type.  For example:
/// decodable_enum! {
///     Color<u8> {
///        Red => 1,
///        Blue => 2,
///        Green => 3,
///     }
/// }
/// Then Color::try_from(2) returns Color::Red, and u8::from(Color::Red) returns 1.
macro_rules! decodable_enum {
    ($(#[$meta:meta])* $name:ident<$raw_type:ty> {
        $($variant:ident => $val:expr),*,
    }) => {
        $(#[$meta])*
        #[derive(Debug, PartialEq)]
        pub(crate) enum $name {
            $($variant),*
        }

        tofrom_decodable_enum! {
            $name<$raw_type> {
                $($variant => $val),*,
            }
        }
    }
}

/// The same as decodable_enum, but the struct is public.
macro_rules! pub_decodable_enum {
    ($(#[$meta:meta])* $name:ident<$raw_type:ty> {
        $($variant:ident => $val:expr),*,
    }) => {
        $(#[$meta])*
        #[derive(Debug, PartialEq)]
        pub enum $name {
            $($variant),*
        }

        tofrom_decodable_enum! {
            $name<$raw_type> {
                $($variant => $val),*,
            }
        }
    }
}

/// A From<&$name> for $raw_type implementation and
/// TryFrom<$raw_type> for $name implementation, used by (pub_)decodable_enum
macro_rules! tofrom_decodable_enum {
    ($name:ident<$raw_type:ty> {
        $($variant:ident => $val:expr),*,
    }) => {
        impl From<&$name> for $raw_type {
            fn from(v: &$name) -> $raw_type {
                match v {
                    $($name::$variant => $val),*,
                }
            }
        }

        impl TryFrom<$raw_type> for $name {
            fn try_from(value: $raw_type) -> Result<Self> {
                match value {
                    $($val => Ok($name::$variant)),*,
                    _ => Err(Error::OutOfRange),
                }
            }
        }
    }
}

pub_decodable_enum! {
    /// Error Codes that can be returned as part of a reject message.
    /// See Section 8.20.6
    ErrorCode<u8> {
        // Header Error Codes
        BadHeaderFormat => 0x01,

        // Payload Format Error Codes
        BadLength => 0x11,
        BadAcpSeid => 0x12,
        SepInUse => 0x13,
        SepNotInUse => 0x14,
        BadServiceCategory => 0x17,
        BadPayloadFormat => 0x18,
        NotSupportedCommand => 0x19,
        InvalidCapabilities => 0x1A,

        // Transport Service Capabilities Error Codes
        BadRecoveryType => 0x22,
        BadMediaTransportFormat => 0x23,
        BadRecoveryFormat => 0x25,
        BadRohcFormat => 0x26,
        BadCpFormat => 0x27,
        BadMultiplexingFormat => 0x28,
        UnsupportedConfiguration => 0x29,

        // Procedure Error Codes
        BadState => 0x31,
    }
}

pub(crate) trait TryFrom<T>: Sized {
    fn try_from(value: T) -> Result<Self>;
}

/// A decodable type can be created from a byte buffer.
/// The type returned is separate (copied) from the buffer once decoded.
pub(crate) trait Decodable: Sized {
    /// Decodes into a new object, or returns an error.
    fn decode(buf: &[u8]) -> Result<Self>;
}

/// A encodable type can write itself into a byte buffer.
pub(crate) trait Encodable: Sized {
    /// Returns the number of bytes necessary to encode |self|
    fn encoded_len(&self) -> usize;

    /// Writes the encoded version of |self| at the start of |buf|
    /// |buf| must be at least size() length.
    fn encode(&self, buf: &mut [u8]) -> Result<()>;
}

/// An AVDTP Transaction Label
/// Not used outside the library.  Public as part of some internal Error variants.
/// See Section 8.4.1
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct TxLabel(u8);

// Transaction labels are only 4 bits.
const MAX_TX_LABEL: u8 = 0xF;

impl TryFrom<u8> for TxLabel {
    fn try_from(value: u8) -> Result<Self> {
        if value > MAX_TX_LABEL {
            fx_log_warn!("TxLabel out of range: {}", value);
            Err(Error::OutOfRange)
        } else {
            Ok(TxLabel(value))
        }
    }
}

impl From<&TxLabel> for u8 {
    fn from(v: &TxLabel) -> u8 {
        v.0
    }
}

impl From<&TxLabel> for usize {
    fn from(v: &TxLabel) -> usize {
        v.0 as usize
    }
}

pub_decodable_enum! {
    /// Type of media
    /// USed to specify the type of media on a stream endpoint.
    /// Part of the StreamInformation in Discovery Response.
    /// Defined in the Bluetooth Assigned Numbers
    /// https://www.bluetooth.com/specifications/assigned-numbers/audio-video
    #[derive(Clone)]
    MediaType<u8> {
        Audio => 0x00,
        Video => 0x01,
        Multimedia => 0x02,
    }
}

pub_decodable_enum! {
    /// Type of endpoint (source or sync)
    /// Part of the StreamInformation in Discovery Response.
    /// See Section 8.20.3
    #[derive(Clone)]
    EndpointType<u8> {
        Source => 0x00,
        Sink => 0x01,
    }
}

decodable_enum! {
    /// Indicated whether this paket is part of a fragmented packet set.
    /// See Section 8.4.2
    SignalingPacketType<u8> {
        Single => 0x00,
        Start => 0x01,
        Continue => 0x02,
        End => 0x03,
    }
}

decodable_enum! {
    /// Specifies the command type of each signaling command or the response
    /// type of each response packet.
    /// See Section 8.4.3
    SignalingMessageType<u8> {
        Command => 0x00,
        GeneralReject => 0x01,
        ResponseAccept => 0x02,
        ResponseReject => 0x03,
    }
}

decodable_enum! {
    /// Indicates the signaling command on a command packet.  The same identifier is used on the
    /// response to that command packet.
    /// See Section 8.4.4
    #[derive(Copy, Clone)]
    SignalIdentifier<u8> {
        Discover => 0x01,
        GetCapabilities => 0x02,
        SetConfiguration => 0x03,
        GetConfiguration => 0x04,
        Reconfigure => 0x05,
        Open => 0x06,
        Start => 0x07,
        Close => 0x08,
        Suspend => 0x09,
        Abort => 0x0A,
        SecurityControl => 0x0B,
        GetAllCapabilities => 0x0C,
        DelayReport => 0x0D,
    }
}

#[derive(Debug)]
pub(crate) struct SignalingHeader {
    pub label: TxLabel,
    packet_type: SignalingPacketType,
    message_type: SignalingMessageType,
    num_packets: u8,
    pub signal: SignalIdentifier,
}

impl SignalingHeader {
    pub fn new(
        label: TxLabel, signal: SignalIdentifier, message_type: SignalingMessageType,
    ) -> SignalingHeader {
        SignalingHeader {
            label: label,
            signal: signal,
            message_type: message_type,
            packet_type: SignalingPacketType::Single,
            num_packets: 1,
        }
    }

    pub fn label(&self) -> TxLabel {
        self.label
    }

    pub fn signal(&self) -> SignalIdentifier {
        self.signal
    }

    pub fn is_type(&self, other: SignalingMessageType) -> bool {
        self.message_type == other
    }

    pub fn is_command(&self) -> bool {
        self.is_type(SignalingMessageType::Command)
    }
}

impl Decodable for SignalingHeader {
    fn decode(bytes: &[u8]) -> Result<SignalingHeader> {
        if bytes.len() < 2 {
            return Err(Error::OutOfRange);
        }
        let label = TxLabel::try_from(bytes[0] >> 4)?;
        let packet_type = SignalingPacketType::try_from((bytes[0] >> 2) & 0x3)?;
        let (id_offset, num_packets) = match packet_type {
            SignalingPacketType::Start => {
                if bytes.len() < 3 {
                    return Err(Error::OutOfRange);
                }
                (2, bytes[1])
            }
            _ => (1, 1),
        };
        let signal_id_val = bytes[id_offset] & 0x3F;
        let id = SignalIdentifier::try_from(signal_id_val)
            .map_err(|_| Error::InvalidSignalId(label, signal_id_val))?;
        let header = SignalingHeader {
            label: label,
            packet_type: packet_type,
            message_type: SignalingMessageType::try_from(bytes[0] & 0x3)?,
            signal: id,
            num_packets: num_packets,
        };
        Ok(header)
    }
}

impl Encodable for SignalingHeader {
    fn encoded_len(&self) -> usize {
        if self.num_packets > 1 {
            3
        } else {
            2
        }
    }

    fn encode(&self, buf: &mut [u8]) -> Result<()> {
        if buf.len() < self.encoded_len() {
            return Err(Error::Encoding);
        }
        buf[0] = u8::from(&self.label) << 4
            | u8::from(&self.packet_type) << 2
            | u8::from(&self.message_type);
        buf[1] = u8::from(&self.signal);
        Ok(())
    }
}

/// A Stream Endpoint Identifier, aka SEID, INT SEID, ACP SEID - Sec 8.20.1
/// Valid values are 0x01 - 0x3E
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub struct StreamEndpointId(pub(crate) u8);

impl StreamEndpointId {
    /// Interpret a StreamEndpointId from the upper six bits of a byte, which
    /// is often how it's transmitted in a message.
    pub(crate) fn from_msg(byte: &u8) -> Self {
        StreamEndpointId(byte >> 2)
    }

    /// Produce a byte where the SEID value is placed in the upper six bits,
    /// which is often how it is placed in a mesage.
    pub(crate) fn to_msg(&self) -> u8 {
        self.0 << 2
    }
}

impl TryFrom<u8> for StreamEndpointId {
    fn try_from(value: u8) -> Result<Self> {
        if value == 0 || value > 0x3E {
            Err(Error::OutOfRange)
        } else {
            Ok(StreamEndpointId(value))
        }
    }
}

impl fmt::Display for StreamEndpointId {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{}", self.0)
    }
}

/// The type of the codec in the MediaCodec Service Capability
/// Valid values are defined in the Bluetooth Assigned Numbers and are
/// interpreted differently for different Media Types, so we do not interpret
/// them here.
/// See https://www.bluetooth.com/specifications/assigned-numbers/audio-video
#[derive(Debug, PartialEq)]
pub struct MediaCodecType(u8);

impl MediaCodecType {
    pub fn new(num: u8) -> MediaCodecType {
        MediaCodecType(num)
    }
}

/// The type of content protection used in the Content Protection Service Capability.
/// Defined in the Bluetooth Assigned Numbers
/// https://www.bluetooth.com/specifications/assigned-numbers/audio-video
#[derive(Debug, PartialEq)]
pub enum ContentProtectionType {
    DigitalTransmissionContentProtection, // DTCP, 0x0001
    SerialCopyManagementSystem,           // SCMS-T, 0x0002
}

impl ContentProtectionType {
    fn to_le_bytes(&self) -> [u8; 2] {
        match self {
            ContentProtectionType::DigitalTransmissionContentProtection => [0x01, 0x00],
            ContentProtectionType::SerialCopyManagementSystem => [0x02, 0x00],
        }
    }
}

impl TryFrom<u16> for ContentProtectionType {
    fn try_from(val: u16) -> Result<Self> {
        match val {
            1 => Ok(ContentProtectionType::DigitalTransmissionContentProtection),
            2 => Ok(ContentProtectionType::SerialCopyManagementSystem),
            _ => Err(Error::OutOfRange),
        }
    }
}

pub_decodable_enum! {
    /// Indicates the signaling command on a command packet.  The same identifier is used on the
    /// response to that command packet.
    /// See Section 8.4.4
    ServiceCategory<u8> {
        None => 0x00,
        MediaTransport => 0x01,
        Reporting => 0x02,
        Recovery => 0x03,
        ContentProtection => 0x04,
        HeaderCompression => 0x05,
        Multiplexing => 0x06,
        MediaCodec => 0x07,
        DelayReporting => 0x08,
    }
}
/// Service Capabilities indicate possible services that can be provided by
/// each stream endpoint.  See AVDTP Spec section 8.21.
#[derive(Debug, PartialEq)]
pub enum ServiceCapability {
    /// Indicates that the end point can provide at least basic media transport
    /// service as defined by RFC 3550 and outlined in section 7.2.
    /// Defined in section 8.21.2
    MediaTransport,
    /// Indicates that the end point can provide reporting service as outlined in section 7.3
    /// Defined in section 8.21.3
    Reporting,
    /// Indicates the end point can provide recovery service as outlined in section 7.4
    /// Defined in section 8.21.4
    Recovery {
        recovery_type: u8,
        max_recovery_window_size: u8,
        max_number_media_packets: u8,
    },
    /// Indicates the codec which is supported by this end point. |codec_extra| is defined within
    /// the relevant profiles (A2DP for Audio, etc).
    /// Defined in section 8.21.5
    MediaCodec {
        media_type: MediaType,
        codec_type: MediaCodecType,
        codec_extra: Vec<u8>, // TODO: Media codec specific information elements
    },
    /// Present when the device has content protection capability.
    /// |extra| is defined elsewhere.
    /// Defined in section 8.21.6
    ContentProtection {
        protection_type: ContentProtectionType,
        extra: Vec<u8>, // Protection speciifc parameters
    },
    /// Indicates that delay reporting is offered by this end point.
    /// Defined in section 8.21.9
    DelayReporting,
}

impl ServiceCapability {
    pub(crate) fn to_category_byte(&self) -> u8 {
        match self {
            ServiceCapability::MediaTransport => &ServiceCategory::MediaTransport,
            ServiceCapability::Reporting => &ServiceCategory::Reporting,
            ServiceCapability::Recovery { .. } => &ServiceCategory::Recovery,
            ServiceCapability::ContentProtection { .. } => &ServiceCategory::ContentProtection,
            ServiceCapability::MediaCodec { .. } => &ServiceCategory::MediaCodec,
            ServiceCapability::DelayReporting => &ServiceCategory::DelayReporting,
        }
        .into()
    }

    pub(crate) fn length_of_service_capabilities(&self) -> u8 {
        match self {
            ServiceCapability::MediaTransport => 0,
            ServiceCapability::Reporting => 0,
            ServiceCapability::Recovery { .. } => 3,
            ServiceCapability::MediaCodec { codec_extra, .. } => 2 + codec_extra.len() as u8,
            ServiceCapability::ContentProtection { extra, .. } => 2 + extra.len() as u8,
            ServiceCapability::DelayReporting => 0,
        }
    }

    /// True when this ServiceCapability is a "basic" capability.
    /// See Table 8.47 in Section 8.21.1
    pub(crate) fn is_basic(&self) -> bool {
        match self {
            ServiceCapability::DelayReporting => false,
            _ => true,
        }
    }

    /// True when this capability should be included in the response to a |sig| command.
    pub(crate) fn in_response(&self, sig: SignalIdentifier) -> bool {
        sig == SignalIdentifier::GetAllCapabilities || self.is_basic()
    }

    /// True when this capability is classified as an "Application Service Capability"
    pub(crate) fn is_application(&self) -> bool {
        match self {
            ServiceCapability::MediaCodec { .. } | ServiceCapability::ContentProtection { .. } => {
                true
            }
            _ => false,
        }
    }
}

impl Decodable for ServiceCapability {
    fn decode(from: &[u8]) -> Result<Self> {
        if from.len() < 2 {
            return Err(Error::Encoding);
        }
        let length_of_capability = from[1] as usize;
        let d = match ServiceCategory::try_from(from[0]) {
            Ok(ServiceCategory::MediaTransport) => match length_of_capability {
                0 => ServiceCapability::MediaTransport,
                _ => return Err(Error::RequestInvalid(ErrorCode::BadMediaTransportFormat)),
            },
            Ok(ServiceCategory::Reporting) => match length_of_capability {
                0 => ServiceCapability::Reporting,
                _ => return Err(Error::RequestInvalid(ErrorCode::BadPayloadFormat)),
            },
            Ok(ServiceCategory::Recovery) => {
                if from.len() < 5 || length_of_capability != 3 {
                    return Err(Error::RequestInvalid(ErrorCode::BadRecoveryFormat));
                }
                let recovery_type = from[2];
                let mrws = from[3];
                let mnmp = from[4];
                // Check format of parameters. See Section 8.21.4, Table 8.51
                // The only recovery type is RFC2733 (0x01)
                if recovery_type != 0x01 {
                    return Err(Error::RequestInvalid(ErrorCode::BadRecoveryType));
                }
                // The MRWS and MNMP must be 0x01 - 0x18
                if mrws < 0x01 || mrws > 0x18 || mnmp < 0x01 || mnmp > 0x18 {
                    return Err(Error::RequestInvalid(ErrorCode::BadRecoveryFormat));
                }
                ServiceCapability::Recovery {
                    recovery_type,
                    max_recovery_window_size: mrws,
                    max_number_media_packets: mnmp,
                }
            }
            Ok(ServiceCategory::ContentProtection) => {
                let cp_format_err = Err(Error::RequestInvalid(ErrorCode::BadCpFormat));
                if from.len() < 4
                    || length_of_capability < 2
                    || from.len() < length_of_capability + 2
                {
                    return cp_format_err;
                }
                let cp_type: u16 = ((from[3] as u16) << 8) + from[2] as u16;
                let protection_type = match ContentProtectionType::try_from(cp_type) {
                    Ok(val) => val,
                    Err(_) => return cp_format_err,
                };
                let extra_len = length_of_capability - 2;
                let mut extra = vec![0; extra_len];
                extra.copy_from_slice(&from[4..4 + extra_len]);
                ServiceCapability::ContentProtection {
                    protection_type,
                    extra,
                }
            }
            Ok(ServiceCategory::MediaCodec) => {
                let format_err = Err(Error::RequestInvalid(ErrorCode::BadPayloadFormat));
                if from.len() < 4
                    || length_of_capability < 2
                    || from.len() < length_of_capability + 2
                {
                    return format_err;
                }
                let media_type = match MediaType::try_from(from[2] >> 4) {
                    Ok(media) => media,
                    Err(_) => return format_err,
                };
                let codec_type = MediaCodecType::new(from[3]);
                let extra_len = length_of_capability - 2;
                let mut codec_extra = vec![0; extra_len];
                codec_extra.copy_from_slice(&from[4..4 + extra_len]);
                ServiceCapability::MediaCodec {
                    media_type,
                    codec_type,
                    codec_extra,
                }
            }
            Ok(ServiceCategory::DelayReporting) => match length_of_capability {
                0 => ServiceCapability::DelayReporting,
                _ => return Err(Error::RequestInvalid(ErrorCode::BadPayloadFormat)),
            },
            _ => {
                return Err(Error::RequestInvalid(ErrorCode::BadServiceCategory));
            }
        };
        Ok(d)
    }
}

impl Encodable for ServiceCapability {
    fn encoded_len(&self) -> usize {
        2 + self.length_of_service_capabilities() as usize
    }

    fn encode(&self, buf: &mut [u8]) -> Result<()> {
        if buf.len() < self.encoded_len() {
            return Err(Error::Encoding);
        }
        let mut cursor = Cursor::new(buf);
        cursor
            .write(&[
                self.to_category_byte(),
                self.length_of_service_capabilities(),
            ])
            .map_err(|_| Error::Encoding)?;
        match self {
            ServiceCapability::Recovery {
                recovery_type: t,
                max_recovery_window_size: max_size,
                max_number_media_packets: max_packets,
            } => {
                cursor
                    .write(&[*t, *max_size, *max_packets])
                    .map_err(|_| Error::Encoding)?;
            }
            ServiceCapability::MediaCodec {
                media_type,
                codec_type,
                codec_extra,
            } => {
                cursor
                    .write(&[u8::from(media_type) << 4, codec_type.0])
                    .map_err(|_| Error::Encoding)?;
                cursor
                    .write(codec_extra.as_slice())
                    .map_err(|_| Error::Encoding)?;
            }
            ServiceCapability::ContentProtection {
                protection_type,
                extra,
            } => {
                cursor
                    .write(&protection_type.to_le_bytes())
                    .map_err(|_| Error::Encoding)?;
                cursor
                    .write(extra.as_slice())
                    .map_err(|_| Error::Encoding)?;
            }
            _ => {}
        }
        Ok(())
    }
}

/// All information related to a stream. Part of the Discovery Response.
/// See Sec 8.6.2
#[derive(Debug, PartialEq)]
pub struct StreamInformation {
    id: StreamEndpointId,
    in_use: bool,
    media_type: MediaType,
    endpoint_type: EndpointType,
}

impl StreamInformation {
    /// Create a new StreamInformation from an ID.
    /// This will only fail if the ID given is out of the range of valid SEIDs (0x01 - 0x3E)
    pub fn new(
        id: StreamEndpointId, in_use: bool, media_type: MediaType, endpoint_type: EndpointType,
    ) -> StreamInformation {
        StreamInformation {
            id: id,
            in_use: in_use,
            media_type: media_type,
            endpoint_type: endpoint_type,
        }
    }

    pub fn id(&self) -> &StreamEndpointId {
        &self.id
    }

    pub fn in_use(&self) -> &bool {
        &self.in_use
    }
}

impl Decodable for StreamInformation {
    fn decode(from: &[u8]) -> Result<Self> {
        if from.len() < 2 {
            return Err(Error::InvalidMessage);
        }
        let id = StreamEndpointId::from_msg(&from[0]);
        let in_use: bool = from[0] & 0x02 != 0;
        let media_type = MediaType::try_from(from[1] >> 4)?;
        let endpoint_type = EndpointType::try_from((from[1] >> 3) & 0x1)?;
        Ok(StreamInformation {
            id: id,
            in_use: in_use,
            media_type: media_type,
            endpoint_type: endpoint_type,
        })
    }
}

impl Encodable for StreamInformation {
    fn encoded_len(&self) -> usize {
        2
    }

    fn encode(&self, into: &mut [u8]) -> Result<()> {
        if into.len() < self.encoded_len() {
            return Err(Error::Encoding);
        }
        into[0] = self.id.to_msg() | if self.in_use { 0x02 } else { 0x00 };
        into[1] = u8::from(&self.media_type) << 4 | u8::from(&self.endpoint_type) << 3;
        Ok(())
    }
}

#[cfg(test)]
mod test {
    use super::*;

    decodable_enum! {
        TestEnum<u16> {
            One => 1,
            Two => 2,
            Max => 65535,
        }
    }

    #[test]
    fn try_from_success() {
        let one = TestEnum::try_from(1);
        assert!(one.is_ok());
        assert_eq!(TestEnum::One, one.unwrap());
        let two = TestEnum::try_from(2);
        assert!(two.is_ok());
        assert_eq!(TestEnum::Two, two.unwrap());
        let max = TestEnum::try_from(65535);
        assert!(max.is_ok());
        assert_eq!(TestEnum::Max, max.unwrap());
    }

    #[test]
    fn try_from_error() {
        let err = TestEnum::try_from(5);
        assert_eq!(Some(Error::OutOfRange), err.err());
    }

    #[test]
    fn into_rawtype() {
        let raw = u16::from(&TestEnum::One);
        assert_eq!(1, raw);
        let raw = u16::from(&TestEnum::Two);
        assert_eq!(2, raw);
        let raw = u16::from(&TestEnum::Max);
        assert_eq!(65535, raw);
    }

    #[test]
    fn txlabel_tofrom_u8() {
        let mut label: Result<TxLabel> = TxLabel::try_from(15);
        assert!(label.is_ok());
        assert_eq!(15, u8::from(&label.unwrap()));
        label = TxLabel::try_from(16);
        assert_eq!(Err(Error::OutOfRange), label);
    }

    #[test]
    fn txlabel_to_usize() {
        let label = TxLabel::try_from(1).unwrap();
        assert_eq!(1, usize::from(&label));
    }
}
