#[cfg(feature = "write_panic_log")]
use sysinfo::{ProcessExt, System, SystemExt};

#[cfg(feature = "write_panic_log")]
fn get_hardware_info(sys_object: &System) -> String {
    let memory_info: String = format!(
        "Used memory: {}/{} bytes.\nUsed swap: {}/{} bytes.",
        sys_object.used_memory(),
        sys_object.total_memory(),
        sys_object.used_swap(),
        sys_object.total_swap()
    );

    let mut cpu_info: String = "CPU LIST:".to_string();
    for cpu in sys_object.cpus() {
        cpu_info.push_str(&format!("\n - {cpu:?}"));
    }

    format!("##### HARDWARE INFORMATION #####\n\n{memory_info}\n{cpu_info}\n\n",)
}

#[cfg(feature = "write_panic_log")]
fn get_software_info(sys_object: &System) -> String {
    let os_info = format!(
        "Running {} with hostname \"{}\". OS version {} with kernel version {}.",
        sys_object
            .name()
            .unwrap_or("[could not fetch OS]".to_string()),
        sys_object
            .host_name()
            .unwrap_or("[could not fetch hostname]".to_string()),
        sys_object
            .os_version()
            .unwrap_or("[could not fetch OS version]".to_string()),
        sys_object
            .kernel_version()
            .unwrap_or("[could not fetch kernel version]".to_string())
    );

    let mut current_process_info: String =
        "Could not fetch information for the current process.".to_string();
    if let Some(process) = sys_object.process(sysinfo::get_current_pid().unwrap()) {
        current_process_info = format!(
            "Current process information:
 - Executable is at path \"{}\".
 - Started at {} unix time, running for {} unix time.
 - Command line: {:?}.
 - Status: {}",
            process.exe().display(),
            process.start_time(),
            process.run_time(),
            process.cmd(),
            process.status()
        );
    }

    format!("##### SOFTWARE INFORMATION #####\n\n{os_info}\n{current_process_info}\n\n",)
}

#[cfg(feature = "write_panic_log")]
pub fn get_info() -> String {
    let mut sys = System::new_all();
    sys.refresh_all();

    let hardware_info = get_hardware_info(&sys);
    let software_info = get_software_info(&sys);

    format!("{hardware_info}\n{software_info}")
}
