// https://chatgpt.com/c/6815e830-74fc-800e-8239-9c3ba042dc58
use cfg_if;
use std::time::Duration;

use anyhow::Result;
use dbus::blocking::Connection;

pub fn is_connection_metered() -> bool {
    cfg_if::cfg_if! {
        if #[cfg(target_os = "linux")] {
            linux_metered().unwrap_or(false)
        } else if #[cfg(target_os = "macos")] {
            macos_metered().unwrap_or(false)
        } else {
            //TODO
            Ok(false)
        }
    }
}

#[cfg(target_os = "linux")]
fn linux_metered() -> Result<bool> {
    use dbus::blocking::stdintf::org_freedesktop_dbus::Properties;
    let conn = Connection::new_system()?;

    // Proxy to NetworkManager
    let proxy = conn.with_proxy(
        "org.freedesktop.NetworkManager",
        "/org/freedesktop/NetworkManager",
        Duration::from_millis(5000),
    );

    // Get list of active connections
    let (active_connections,): (Vec<dbus::Path<'_>>,) =
        proxy.get("org.freedesktop.NetworkManager", "ActiveConnections")?;

    // Check all active connections (usually there's one, but may be more)
    for path in active_connections {
        let conn_proxy = conn.with_proxy(
            "org.freedesktop.NetworkManager",
            path.clone(),
            Duration::from_millis(5000),
        );

        // Get the Metered flag (u32)
        let (metered,): (u32,) = conn_proxy.get(
            "org.freedesktop.NetworkManager.Connection.Active",
            "Metered",
        )?;

        // Interpret metered value:
        // 1 = metered, 3 = assumed metered → return true
        // 2 = not metered, 4 = assumed not metered → return false
        // 0 = unknown → ignore or fallback to false
        match metered {
            1 | 3 => return Ok(true),
            2 | 4 => return Ok(false),
            0 => continue, // unknown – skip to next
            _ => continue,
        }
    }

    // Default: No metered connections found
    Ok(false)
}

#[cfg(target_os = "macos")]
fn macos_metered() -> Result<Option<bool>> {
    use get_if_addrs::get_if_addrs;

    let interfaces = get_if_addrs()?;

    for iface in interfaces {
        if iface.is_loopback() {
            continue;
        }

        let name = iface.name.to_lowercase();

        // Heuristic: if using a known metered-style interface
        if name.contains("pdp_ip")
            || name.contains("bridge")
            || name.contains("cell")
            || name.contains("wwan")
        {
            return Ok(Some(true));
        }
    }

    // If no known metered interfaces found, assume not metered
    Ok(Some(false))
}
