//
// Syd: rock-solid application kernel
// src/utils/syd-size.rs: Given a number, print human-formatted size and exit.
//                  Given a string, parse human-formatted size into bytes, print and exit.
//
// Copyright (c) 2024, 2025 Ali Polatel <alip@chesswob.org>
//
// SPDX-License-Identifier: GPL-3.0

use std::process::ExitCode;

// Set global allocator to GrapheneOS allocator.
#[cfg(all(
    not(coverage),
    not(feature = "prof"),
    not(target_os = "android"),
    target_page_size_4k,
    target_pointer_width = "64"
))]
#[global_allocator]
static GLOBAL: hardened_malloc::HardenedMalloc = hardened_malloc::HardenedMalloc;

// Set global allocator to tcmalloc if profiling is enabled.
#[cfg(feature = "prof")]
#[global_allocator]
static GLOBAL: tcmalloc::TCMalloc = tcmalloc::TCMalloc;

syd::main! {
    syd::set_sigpipe_dfl()?;

    let mut args = std::env::args();

    match args.nth(1).as_deref() {
        None | Some("-h") => {
            println!("Usage: syd-size size");
            println!("Given a number, print human-formatted size and exit.");
            println!("Given a string, parse human-formatted size into bytes, print and exit.");
        }
        Some(value) => {
            if value.chars().all(|c| c.is_ascii_digit()) {
                match value.parse::<usize>() {
                    Ok(size) => {
                        println!("{}", syd::human_size(size));
                    }
                    Err(error) => {
                        eprintln!("Failed to parse: {error}");
                        return Ok(ExitCode::FAILURE);
                    }
                }
            } else {
                match parse_size::Config::new().with_binary().parse_size(value) {
                    Ok(size) => {
                        println!("{size}");
                    }
                    Err(error) => {
                        eprintln!("Failed to parse: {error}");
                        return Ok(ExitCode::FAILURE);
                    }
                }
            }
        }
    }

    Ok(ExitCode::SUCCESS)
}
