use super::{param_header::*, param_type::*, *};
use bytes::{Buf, BufMut, Bytes, BytesMut};
use std::fmt;
#[derive(Debug, Copy, Clone, PartialEq)]
#[repr(C)]
pub(crate) enum ReconfigResult {
    SuccessNop = 0,
    SuccessPerformed = 1,
    Denied = 2,
    ErrorWrongSsn = 3,
    ErrorRequestAlreadyInProgress = 4,
    ErrorBadSequenceNumber = 5,
    InProgress = 6,
    Unknown,
}
impl Default for ReconfigResult {
    fn default() -> Self {
        ReconfigResult::Unknown
    }
}
impl fmt::Display for ReconfigResult {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let s = match *self {
            ReconfigResult::SuccessNop => "0: Success - Nothing to do",
            ReconfigResult::SuccessPerformed => "1: Success - Performed",
            ReconfigResult::Denied => "2: Denied",
            ReconfigResult::ErrorWrongSsn => "3: Error - Wrong SSN",
            ReconfigResult::ErrorRequestAlreadyInProgress => {
                "4: Error - Request already in progress"
            }
            ReconfigResult::ErrorBadSequenceNumber => "5: Error - Bad Sequence Number",
            ReconfigResult::InProgress => "6: In progress",
            _ => "Unknown ReconfigResult",
        };
        write!(f, "{}", s)
    }
}
impl From<u32> for ReconfigResult {
    fn from(v: u32) -> ReconfigResult {
        match v {
            0 => ReconfigResult::SuccessNop,
            1 => ReconfigResult::SuccessPerformed,
            2 => ReconfigResult::Denied,
            3 => ReconfigResult::ErrorWrongSsn,
            4 => ReconfigResult::ErrorRequestAlreadyInProgress,
            5 => ReconfigResult::ErrorBadSequenceNumber,
            6 => ReconfigResult::InProgress,
            _ => ReconfigResult::Unknown,
        }
    }
}
#[derive(Default, Debug, Clone, PartialEq)]
pub(crate) struct ParamReconfigResponse {
    pub(crate) reconfig_response_sequence_number: u32,
    pub(crate) result: ReconfigResult,
}
impl fmt::Display for ParamReconfigResponse {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "{} {} {}",
            self.header(),
            self.reconfig_response_sequence_number,
            self.result
        )
    }
}
impl Param for ParamReconfigResponse {
    fn header(&self) -> ParamHeader {
        ParamHeader {
            typ: ParamType::ReconfigResp,
            value_length: self.value_length() as u16,
        }
    }
    fn unmarshal(raw: &Bytes) -> Result<Self> {
        let header = ParamHeader::unmarshal(raw)?;
        if raw.len() < 8 + PARAM_HEADER_LENGTH {
            return Err(Error::ErrReconfigRespParamTooShort);
        }
        let reader =
            &mut raw.slice(PARAM_HEADER_LENGTH..PARAM_HEADER_LENGTH + header.value_length());
        let reconfig_response_sequence_number = reader.get_u32();
        let result = reader.get_u32().into();
        Ok(ParamReconfigResponse {
            reconfig_response_sequence_number,
            result,
        })
    }
    fn marshal_to(&self, buf: &mut BytesMut) -> Result<usize> {
        self.header().marshal_to(buf)?;
        buf.put_u32(self.reconfig_response_sequence_number);
        buf.put_u32(self.result as u32);
        Ok(buf.len())
    }
    fn value_length(&self) -> usize {
        8
    }
    fn clone_to(&self) -> Box<dyn Param + Send + Sync> {
        Box::new(self.clone())
    }
    fn as_any(&self) -> &(dyn Any + Send + Sync) {
        self
    }
}