// SPDX-License-Identifier: MIT

use std::env::args;

use anyhow::{bail, Error};
use futures::StreamExt;
use genetlink::new_connection;
use netlink_packet_core::{
    NetlinkHeader, NetlinkMessage, NetlinkPayload, NLM_F_DUMP, NLM_F_REQUEST,
};
use netlink_packet_generic::{
    ctrl::{nlas::GenlCtrlAttrs, GenlCtrl, GenlCtrlCmd},
    GenlMessage,
};

#[tokio::main]
async fn main() -> Result<(), Error> {
    let argv: Vec<_> = args().collect();

    if argv.len() < 2 {
        eprintln!("Usage: dump_family_policy <family name>");
        bail!("Required arguments not given");
    }
    let mut nl_hdr = NetlinkHeader::default();
    nl_hdr.flags = NLM_F_REQUEST | NLM_F_DUMP;

    let nlmsg = NetlinkMessage::new(
        nl_hdr,
        GenlMessage::from_payload(GenlCtrl {
            cmd: GenlCtrlCmd::GetPolicy,
            nlas: vec![GenlCtrlAttrs::FamilyName(argv[1].to_owned())],
        })
        .into(),
    );
    let (conn, mut handle, _) = new_connection()?;
    tokio::spawn(conn);

    let mut responses = handle.request(nlmsg).await?;

    while let Some(result) = responses.next().await {
        let resp = result?;
        match resp.payload {
            NetlinkPayload::InnerMessage(genlmsg) => {
                if genlmsg.payload.cmd == GenlCtrlCmd::GetPolicy {
                    println!("<<< {genlmsg:?}");
                }
            }
            NetlinkPayload::Error(err) => {
                eprintln!("Received a netlink error message: {err:?}");
                bail!(err);
            }
            _ => {}
        }
    }

    Ok(())
}
