/* Code generated by Azure.Iot.Operations.ProtocolCompilerLib v0.10.0.0; DO NOT EDIT. */

use std::collections::HashMap;

use azure_iot_operations_mqtt::{session::SessionManagedClient, token::AckToken};
use azure_iot_operations_protocol::application::ApplicationContext;
use azure_iot_operations_protocol::common::aio_protocol_error::AIOProtocolError;
use azure_iot_operations_protocol::telemetry;

use super::super::common_types::options::TelemetryReceiverOptions;
use super::MODEL_ID;
use super::TELEMETRY_TOPIC_PATTERN;
use super::device_update_event_telemetry::DeviceUpdateEventTelemetry;

pub type DeviceUpdateEventTelemetryMessage =
    telemetry::receiver::Message<DeviceUpdateEventTelemetry>;

/// Telemetry Receiver for `DeviceUpdateEventTelemetry`
pub struct DeviceUpdateEventTelemetryReceiver(telemetry::Receiver<DeviceUpdateEventTelemetry>);

impl DeviceUpdateEventTelemetryReceiver {
    /// Creates a new [`DeviceUpdateEventTelemetryReceiver`]
    ///
    /// # Panics
    /// If the DTDL that generated this code was invalid
    pub fn new(
        application_context: ApplicationContext,
        client: SessionManagedClient,
        options: &TelemetryReceiverOptions,
    ) -> Self {
        let mut receiver_options_builder = telemetry::receiver::OptionsBuilder::default();
        if let Some(topic_namespace) = &options.topic_namespace {
            receiver_options_builder.topic_namespace(topic_namespace.clone());
        }

        let mut topic_token_map: HashMap<String, String> = options
            .topic_token_map
            .clone()
            .into_iter()
            .map(|(k, v)| (format!("ex:{k}"), v))
            .collect();

        topic_token_map.insert("modelId".to_string(), MODEL_ID.to_string());
        topic_token_map.insert("telemetryName".to_string(), "deviceUpdateEvent".to_string());

        let receiver_options = receiver_options_builder
            .topic_pattern(TELEMETRY_TOPIC_PATTERN)
            .topic_token_map(topic_token_map)
            .auto_ack(options.auto_ack)
            .build()
            .expect("DTDL schema generated invalid arguments");

        Self(
            telemetry::Receiver::new(application_context, client, receiver_options)
                .expect("DTDL schema generated invalid arguments"),
        )
    }

    /// Shut down the [`DeviceUpdateEventTelemetryReceiver`]
    ///
    /// # Errors
    /// [`AIOProtocolError`] if there is a failure in graceful shutdown
    pub async fn shutdown(&mut self) -> Result<(), AIOProtocolError> {
        self.0.shutdown().await
    }

    /// Receive the next [`DeviceUpdateEventTelemetryMessage`]
    ///
    /// # Errors
    /// [`AIOProtocolError`] if there is a failure receiving a message
    pub async fn recv(
        &mut self,
    ) -> Option<Result<(DeviceUpdateEventTelemetryMessage, Option<AckToken>), AIOProtocolError>>
    {
        self.0.recv().await
    }
}
