use alloc::{boxed::Box, sync::Arc, vec::Vec};
use libk::vfs::ChannelDescriptor;
use serde::Serialize;
use yggdrasil_abi::{
    error::Error,
    io::{ChannelPublisherId, MessageDestination},
    net::{
        netconfig::{
            InterfaceInfo, InterfaceQuery, NetConfigRequest, NetConfigResult, RouteInfo,
            RoutingInfo,
        },
        IpAddr, SubnetAddr,
    },
};

use crate::{
    interface::NetworkInterface,
    l3::{arp, Route},
};

async fn receive_request(
    channel: &ChannelDescriptor,
) -> Result<(ChannelPublisherId, NetConfigRequest), Error> {
    todo!()
    // loop {
    //     let raw = channel.receive_message_async().await?;
    //     match &raw.payload {
    //         MessagePayload::Data(message) => {
    //             let msg =
    //                 serde_json::from_slice(message.as_ref()).map_err(|_| Error::InvalidArgument)?;

    //             return Ok((raw.source, msg));
    //         }
    //         MessagePayload::File(_) => (),
    //     }
    // }
}

fn send_reply<T: Serialize>(
    channel: &ChannelDescriptor,
    recepient: ChannelPublisherId,
    message: NetConfigResult<T>,
) -> Result<(), Error> {
    todo!()
    // let data = serde_json::to_vec(&message).map_err(|_| Error::InvalidArgument)?;
    // channel.send_message(
    //     MessagePayload::Data(data.into_boxed_slice()),
    //     MessageDestination::Specific(recepient.into()),
    // )
}

fn list_interfaces() -> Vec<(Box<str>, u32)> {
    let interfaces = NetworkInterface::list_ref();
    interfaces
        .iter()
        .map(|(&id, iface)| (iface.name.clone(), id))
        .collect()
}

pub async fn network_config_service() -> Result<(), Error> {
    let channel = ChannelDescriptor::open("@kernel-netconf", true);

    loop {
        let (sender_id, request) = receive_request(&channel).await?;

        match request {
            NetConfigRequest::SetNetworkAddress { interface, address } => {}
            NetConfigRequest::QueryRoute(destination) => {}
            NetConfigRequest::QueryArp(interface_id, destination, perform_query) => {}
        }
    }
}
