autosar_data_abstraction/communication/network_management/
udp_nm.rsuse crate::communication::{
    AbstractNmCluster, AbstractNmClusterCoupling, AbstractNmNode, EthernetCluster, EthernetCommunicationController,
    EthernetPhysicalChannel, NmEcu,
};
use crate::{abstraction_element, AbstractionElement, AutosarAbstractionError};
use autosar_data::{Element, ElementName};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct UdpNmCluster(Element);
abstraction_element!(UdpNmCluster, UdpNmCluster);
impl UdpNmCluster {
    pub(crate) fn new(
        name: &str,
        parent: &Element,
        settings: &UdpNmClusterSettings,
        ethernet_cluster: &EthernetCluster,
    ) -> Result<Self, AutosarAbstractionError> {
        let nm_cluster = parent.create_named_sub_element(ElementName::UdpNmCluster, name)?;
        let udp_nm_cluster = Self(nm_cluster);
        udp_nm_cluster.set_communication_cluster(ethernet_cluster)?;
        udp_nm_cluster.set_nm_msg_cycle_time(settings.nm_msg_cycle_time)?;
        udp_nm_cluster.set_nm_message_timeout_time(settings.nm_msg_timeout_time)?;
        udp_nm_cluster.set_nm_network_timeout(settings.nm_network_timeout)?;
        udp_nm_cluster.set_nm_remote_sleep_indication_time(settings.nm_remote_sleep_indication_time)?;
        udp_nm_cluster.set_nm_repeat_message_time(settings.nm_repeat_message_time)?;
        udp_nm_cluster.set_nm_wait_bus_sleep_time(settings.nm_wait_bus_sleep_time)?;
        Ok(udp_nm_cluster)
    }
    pub fn set_nm_msg_cycle_time(&self, cycle_time: f64) -> Result<(), AutosarAbstractionError> {
        self.element()
            .get_or_create_sub_element(ElementName::NmMsgCycleTime)?
            .set_character_data(cycle_time)?;
        Ok(())
    }
    #[must_use]
    pub fn nm_msg_cycle_time(&self) -> Option<f64> {
        self.element()
            .get_sub_element(ElementName::NmMsgCycleTime)
            .and_then(|elem| elem.character_data())
            .and_then(|cdata| cdata.parse_float())
    }
    pub fn set_nm_message_timeout_time(&self, timeout_time: f64) -> Result<(), AutosarAbstractionError> {
        self.element()
            .get_or_create_sub_element(ElementName::NmMessageTimeoutTime)?
            .set_character_data(timeout_time)?;
        Ok(())
    }
    #[must_use]
    pub fn nm_message_timeout_time(&self) -> Option<f64> {
        self.element()
            .get_sub_element(ElementName::NmMessageTimeoutTime)
            .and_then(|elem| elem.character_data())
            .and_then(|cdata| cdata.parse_float())
    }
    pub fn set_nm_network_timeout(&self, timeout: f64) -> Result<(), AutosarAbstractionError> {
        self.element()
            .get_or_create_sub_element(ElementName::NmNetworkTimeout)?
            .set_character_data(timeout)?;
        Ok(())
    }
    #[must_use]
    pub fn nm_network_timeout(&self) -> Option<f64> {
        self.element()
            .get_sub_element(ElementName::NmNetworkTimeout)
            .and_then(|elem| elem.character_data())
            .and_then(|cdata| cdata.parse_float())
    }
    pub fn set_nm_remote_sleep_indication_time(&self, time: f64) -> Result<(), AutosarAbstractionError> {
        self.element()
            .get_or_create_sub_element(ElementName::NmRemoteSleepIndicationTime)?
            .set_character_data(time)?;
        Ok(())
    }
    #[must_use]
    pub fn nm_remote_sleep_indication_time(&self) -> Option<f64> {
        self.element()
            .get_sub_element(ElementName::NmRemoteSleepIndicationTime)
            .and_then(|elem| elem.character_data())
            .and_then(|cdata| cdata.parse_float())
    }
    pub fn set_nm_repeat_message_time(&self, time: f64) -> Result<(), AutosarAbstractionError> {
        self.element()
            .get_or_create_sub_element(ElementName::NmRepeatMessageTime)?
            .set_character_data(time)?;
        Ok(())
    }
    #[must_use]
    pub fn nm_repeat_message_time(&self) -> Option<f64> {
        self.element()
            .get_sub_element(ElementName::NmRepeatMessageTime)
            .and_then(|elem| elem.character_data())
            .and_then(|cdata| cdata.parse_float())
    }
    pub fn set_nm_wait_bus_sleep_time(&self, time: f64) -> Result<(), AutosarAbstractionError> {
        self.element()
            .get_or_create_sub_element(ElementName::NmWaitBusSleepTime)?
            .set_character_data(time)?;
        Ok(())
    }
    #[must_use]
    pub fn nm_wait_bus_sleep_time(&self) -> Option<f64> {
        self.element()
            .get_sub_element(ElementName::NmWaitBusSleepTime)
            .and_then(|elem| elem.character_data())
            .and_then(|cdata| cdata.parse_float())
    }
    pub fn create_udp_nm_node(
        &self,
        name: &str,
        controller: &EthernetCommunicationController,
        nm_ecu: &NmEcu,
        nm_msg_cycle_offset: f64,
    ) -> Result<UdpNmNode, AutosarAbstractionError> {
        let nm_nodes = self.element().get_or_create_sub_element(ElementName::NmNodes)?;
        UdpNmNode::new(name, &nm_nodes, controller, nm_ecu, nm_msg_cycle_offset)
    }
    pub fn set_vlan(&self, vlan: Option<&EthernetPhysicalChannel>) -> Result<(), AutosarAbstractionError> {
        if let Some(vlan) = vlan {
            self.element()
                .get_or_create_sub_element(ElementName::VlanRef)?
                .set_reference_target(vlan.element())?;
        } else {
            self.element().remove_sub_element_kind(ElementName::VlanRef)?;
        }
        Ok(())
    }
    #[must_use]
    pub fn vlan(&self) -> Option<EthernetPhysicalChannel> {
        self.element()
            .get_sub_element(ElementName::VlanRef)
            .and_then(|vlan_ref| vlan_ref.get_reference_target().ok())
            .and_then(|elem| elem.try_into().ok())
    }
    pub fn set_nm_immediate_nm_transmissions(&self, value: Option<u32>) -> Result<(), AutosarAbstractionError> {
        if let Some(value) = value {
            self.element()
                .get_or_create_sub_element(ElementName::NmImmediateNmTransmissions)?
                .set_character_data(u64::from(value))?;
        } else {
            self.element()
                .remove_sub_element_kind(ElementName::NmImmediateNmTransmissions)?;
        }
        Ok(())
    }
    #[must_use]
    pub fn nm_immediate_nm_transmissions(&self) -> Option<u32> {
        self.element()
            .get_sub_element(ElementName::NmImmediateNmTransmissions)
            .and_then(|elem| elem.character_data())
            .and_then(|cdata| cdata.parse_integer())
    }
    pub fn set_nm_cbv_position(&self, value: Option<u32>) -> Result<(), AutosarAbstractionError> {
        if let Some(value) = value {
            self.element()
                .get_or_create_sub_element(ElementName::NmCbvPosition)?
                .set_character_data(u64::from(value))?;
        } else {
            self.element().remove_sub_element_kind(ElementName::NmCbvPosition)?;
        }
        Ok(())
    }
    #[must_use]
    pub fn nm_cbv_position(&self) -> Option<u32> {
        self.element()
            .get_sub_element(ElementName::NmCbvPosition)
            .and_then(|elem| elem.character_data())
            .and_then(|cdata| cdata.parse_integer())
    }
    pub fn set_nm_nid_position(&self, value: Option<u32>) -> Result<(), AutosarAbstractionError> {
        if let Some(value) = value {
            self.element()
                .get_or_create_sub_element(ElementName::NmNidPosition)?
                .set_character_data(u64::from(value))?;
        } else {
            self.element().remove_sub_element_kind(ElementName::NmNidPosition)?;
        }
        Ok(())
    }
    #[must_use]
    pub fn nm_nid_position(&self) -> Option<u32> {
        self.element()
            .get_sub_element(ElementName::NmNidPosition)
            .and_then(|elem| elem.character_data())
            .and_then(|cdata| cdata.parse_integer())
    }
}
impl AbstractNmCluster for UdpNmCluster {
    type CommunicationClusterType = EthernetCluster;
    type NmNodeType = UdpNmNode;
}
#[derive(Debug, Clone, PartialEq)]
pub struct UdpNmClusterSettings {
    pub nm_msg_cycle_time: f64,
    pub nm_msg_timeout_time: f64,
    pub nm_network_timeout: f64,
    pub nm_remote_sleep_indication_time: f64,
    pub nm_repeat_message_time: f64,
    pub nm_wait_bus_sleep_time: f64,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct UdpNmClusterCoupling(Element);
abstraction_element!(UdpNmClusterCoupling, UdpNmClusterCoupling);
impl UdpNmClusterCoupling {
    pub(crate) fn new(parent: &Element) -> Result<Self, AutosarAbstractionError> {
        let nm_cluster_coupling = parent.create_sub_element(ElementName::UdpNmClusterCoupling)?;
        Ok(Self(nm_cluster_coupling))
    }
    pub fn set_nm_immediate_restart_enabled(&self, enabled: Option<bool>) -> Result<(), AutosarAbstractionError> {
        if let Some(enabled) = enabled {
            self.element()
                .get_or_create_sub_element(ElementName::NmImmediateRestartEnabled)?
                .set_character_data(enabled)?;
        } else {
            self.element()
                .remove_sub_element_kind(ElementName::NmImmediateRestartEnabled)?;
        }
        Ok(())
    }
    #[must_use]
    pub fn nm_immediate_restart_enabled(&self) -> Option<bool> {
        self.element()
            .get_sub_element(ElementName::NmImmediateRestartEnabled)
            .and_then(|elem| elem.character_data())
            .and_then(|cdata| cdata.parse_bool())
    }
}
impl AbstractNmClusterCoupling for UdpNmClusterCoupling {
    type NmClusterType = UdpNmCluster;
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct UdpNmNode(Element);
abstraction_element!(UdpNmNode, UdpNmNode);
impl UdpNmNode {
    pub(crate) fn new(
        name: &str,
        parent: &Element,
        controller: &EthernetCommunicationController,
        nm_ecu: &NmEcu,
        nm_msg_cycle_offset: f64,
    ) -> Result<Self, AutosarAbstractionError> {
        let udp_nm_node_elem = parent.create_named_sub_element(ElementName::UdpNmNode, name)?;
        let udp_nm_node = Self(udp_nm_node_elem);
        udp_nm_node.set_communication_controller(controller)?;
        udp_nm_node.set_nm_ecu(nm_ecu)?;
        udp_nm_node.set_nm_msg_cycle_offset(nm_msg_cycle_offset)?;
        Ok(udp_nm_node)
    }
    pub fn set_nm_msg_cycle_offset(&self, offset: f64) -> Result<(), AutosarAbstractionError> {
        self.element()
            .get_or_create_sub_element(ElementName::NmMsgCycleOffset)?
            .set_character_data(offset)?;
        Ok(())
    }
    #[must_use]
    pub fn nm_msg_cycle_offset(&self) -> Option<f64> {
        self.element()
            .get_sub_element(ElementName::NmMsgCycleOffset)
            .and_then(|elem| elem.character_data())
            .and_then(|cdata| cdata.parse_float())
    }
    pub fn set_all_nm_messages_keep_awake(&self, enabled: Option<bool>) -> Result<(), AutosarAbstractionError> {
        if let Some(enabled) = enabled {
            self.element()
                .get_or_create_sub_element(ElementName::AllNmMessagesKeepAwake)?
                .set_character_data(enabled)?;
        } else {
            self.element()
                .remove_sub_element_kind(ElementName::AllNmMessagesKeepAwake)?;
        }
        Ok(())
    }
    #[must_use]
    pub fn all_nm_messages_keep_awake(&self) -> Option<bool> {
        self.element()
            .get_sub_element(ElementName::AllNmMessagesKeepAwake)
            .and_then(|elem| elem.character_data())
            .and_then(|cdata| cdata.parse_bool())
    }
}
impl AbstractNmNode for UdpNmNode {
    type CommunicationControllerType = EthernetCommunicationController;
}