use std::process::Command;

#[derive( Clone )]
pub struct MountInfo
{
	pub mount: String,
	pub used:  u64,
	pub total: u64,
}

/// Best-effort `df` snapshot of the root filesystem. Returns an empty
/// vector if `df` is missing or its output cannot be parsed (e.g.
/// containers without /proc/mounts). The settings view treats an
/// empty list as "no storage info".
pub fn scan() -> Vec<MountInfo>
{
	let output = Command::new( "df" )
		.args( ["-B1", "-P", "/"] )
		.output().ok();

	let text = output
		.and_then( |o| String::from_utf8( o.stdout ).ok() )
		.unwrap_or_default();

	text.lines().skip( 1 ).filter_map( |line|
	{
		let parts: Vec<&str> = line.split_whitespace().collect();
		// df -P fields: Filesystem 1B-blocks Used Available Capacity Mounted-on
		if parts.len() < 6 { return None; }
		let total: u64 = parts[1].parse().ok()?;
		let used:  u64 = parts[2].parse().ok()?;
		Some( MountInfo { mount: parts[5].to_string(), used, total } )
	}).collect()
}

pub fn fmt_bytes( b: u64 ) -> String
{
	const KB: f64 = 1024.0;
	const MB: f64 = KB * 1024.0;
	const GB: f64 = MB * 1024.0;
	const TB: f64 = GB * 1024.0;
	let b = b as f64;
	if      b >= TB { format!( "{:.1} TB", b / TB ) }
	else if b >= GB { format!( "{:.1} GB", b / GB ) }
	else if b >= MB { format!( "{:.0} MB", b / MB ) }
	else if b >= KB { format!( "{:.0} KB", b / KB ) }
	else            { format!( "{} B", b as u64 ) }
}
