use protobuf::EnumFull;
use crate::uattributes::UAttributesError;
pub use crate::up_core_api::uattributes::UMessageType;
use crate::up_core_api::uoptions::exts::ce_name;
impl UMessageType {
    pub fn to_cloudevent_type(&self) -> String {
        let desc = self.descriptor();
        let desc_proto = desc.proto();
        ce_name
            .get(desc_proto.options.get_or_default())
            .unwrap_or_default()
    }
    pub fn try_from_cloudevent_type<S: Into<String>>(value: S) -> Result<Self, UAttributesError> {
        let type_string = value.into();
        Self::enum_descriptor()
            .values()
            .find_map(|desc| {
                let proto_desc = desc.proto();
                ce_name
                    .get(proto_desc.options.get_or_default())
                    .and_then(|prio_option_value| {
                        if prio_option_value.eq(type_string.as_str()) {
                            desc.cast::<Self>()
                        } else {
                            None
                        }
                    })
            })
            .ok_or_else(|| {
                UAttributesError::parsing_error(format!("unknown message type: {}", type_string))
            })
    }
}
#[cfg(test)]
mod tests {
    use test_case::test_case;
    use crate::{UAttributesError, UMessageType};
    const TYPE_PUBLISH: &str = "pub.v1";
    const TYPE_NOTIFICATION: &str = "not.v1";
    const TYPE_REQUEST: &str = "req.v1";
    const TYPE_RESPONSE: &str = "res.v1";
    #[test_case(UMessageType::UMESSAGE_TYPE_PUBLISH, TYPE_PUBLISH; "for PUBLISH")]
    #[test_case(UMessageType::UMESSAGE_TYPE_NOTIFICATION, TYPE_NOTIFICATION; "for NOTIFICATION")]
    #[test_case(UMessageType::UMESSAGE_TYPE_REQUEST, TYPE_REQUEST; "for REQUEST")]
    #[test_case(UMessageType::UMESSAGE_TYPE_RESPONSE, TYPE_RESPONSE; "for RESPONSE")]
    fn test_to_cloudevent_type(message_type: UMessageType, expected_ce_name: &str) {
        assert_eq!(message_type.to_cloudevent_type(), expected_ce_name);
    }
    #[test_case(TYPE_PUBLISH, Some(UMessageType::UMESSAGE_TYPE_PUBLISH); "succeeds for PUBLISH")]
    #[test_case(TYPE_NOTIFICATION, Some(UMessageType::UMESSAGE_TYPE_NOTIFICATION); "succeeds for NOTIFICATION")]
    #[test_case(TYPE_REQUEST, Some(UMessageType::UMESSAGE_TYPE_REQUEST); "succeeds for REQUEST")]
    #[test_case(TYPE_RESPONSE, Some(UMessageType::UMESSAGE_TYPE_RESPONSE); "succeeds for RESPONSE")]
    #[test_case("foo.bar", None; "fails for unknown type")]
    fn test_try_from_cloudevent_type(
        cloudevent_type: &str,
        expected_message_type: Option<UMessageType>,
    ) {
        let result = UMessageType::try_from_cloudevent_type(cloudevent_type);
        assert!(result.is_ok() == expected_message_type.is_some());
        if expected_message_type.is_some() {
            assert_eq!(result.unwrap(), expected_message_type.unwrap())
        } else {
            assert!(matches!(
                result.unwrap_err(),
                UAttributesError::ParsingError(_msg)
            ))
        }
    }
}