//! `mavlink_layer` — hand-rolled MAVLink v2 transport.
//!
//! Real implementation lands in:
//! - AZ-641 `mavlink_transport_and_heartbeat`
//! - AZ-642 `mavlink_codec`
//! - AZ-643 `mavlink_ack_demux_and_signing`

use async_trait::async_trait;

use shared::contracts::MavlinkSink;
use shared::error::{AutopilotError, Result};
use shared::health::ComponentHealth;

const NAME: &str = "mavlink_layer";

#[derive(Debug, Clone)]
pub struct MavlinkConnection {
    pub uri: String,
}

#[derive(Debug, Clone)]
pub struct MavlinkLayer {
    connection: MavlinkConnection,
}

impl MavlinkLayer {
    pub fn new(connection: MavlinkConnection) -> Self {
        Self { connection }
    }

    pub fn handle(&self) -> MavlinkHandle {
        MavlinkHandle::new(self.connection.clone())
    }
}

#[derive(Debug, Clone)]
pub struct MavlinkHandle {
    #[allow(dead_code)]
    connection: MavlinkConnection,
}

impl MavlinkHandle {
    pub(crate) fn new(connection: MavlinkConnection) -> Self {
        Self { connection }
    }

    pub async fn send_raw(&self, _payload: Vec<u8>) -> Result<()> {
        Err(AutopilotError::NotImplemented(
            "mavlink_layer::send_raw (AZ-641)",
        ))
    }

    pub fn health(&self) -> ComponentHealth {
        ComponentHealth::disabled(NAME)
    }
}

#[async_trait]
impl MavlinkSink for MavlinkHandle {
    async fn send_raw(&self, msg: Vec<u8>) -> Result<()> {
        MavlinkHandle::send_raw(self, msg).await
    }
}

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

    #[test]
    fn it_compiles() {
        // Arrange / Act
        let h = MavlinkLayer::new(MavlinkConnection {
            uri: "udp://127.0.0.1:14550".into(),
        })
        .handle();

        // Assert
        assert_eq!(h.health().level, shared::health::HealthLevel::Disabled);
    }
}
