use std::fs::Metadata;
use std::path::{Path, PathBuf};

/// Return the physical (on-disk) size of a file.
/// On Unix, uses block count to handle sparse files and APFS clones correctly.
/// Falls back to logical size on other platforms.
pub fn physical_size(metadata: &Metadata) -> u64 {
    #[cfg(unix)]
    {
        use std::os::unix::fs::MetadataExt;
        // blocks() returns 512-byte blocks (POSIX convention)
        metadata.blocks() * 512
    }
    #[cfg(not(unix))]
    {
        metadata.len()
    }
}

/// Recursively compute the total size of a directory.
/// Uses jwalk for parallel directory reading on modern storage.
pub fn dir_size(path: &Path) -> u64 {
    if path.is_file() {
        return path.metadata().map(|m| physical_size(&m)).unwrap_or(0);
    }

    jwalk::WalkDir::new(path)
        .skip_hidden(false)
        .follow_links(false)
        .into_iter()
        .filter_map(|e| e.ok())
        .filter(|e| e.file_type().is_file())
        .map(|e| e.metadata().map(|m| physical_size(&m)).unwrap_or(0))
        .sum()
}

/// Check whether a file's magic bytes match the given MIME type prefix (e.g. "image/", "video/").
pub fn has_mime_prefix(path: &Path, prefix: &str) -> bool {
    match infer::get_from_path(path) {
        Ok(Some(kind)) => kind.mime_type().starts_with(prefix),
        _ => false,
    }
}

/// Return the user's home directory.
pub fn home_dir() -> PathBuf {
    dirs::home_dir().expect("could not determine home directory")
}
