//
// Syd: rock-solid application kernel
// src/syd-stat.rs: Print process status of the given PID or the current process.
//
// Copyright (c) 2024 Ali Polatel <alip@chesswob.org>
//
// SPDX-License-Identifier: GPL-3.0

#![recursion_limit = "256"]

use std::process::ExitCode;

use nix::{libc::pid_t, unistd::Pid};
use serde_json::json;
use syd::{
    err::SydResult,
    proc::{proc_stat, proc_status},
};

fn main() -> SydResult<ExitCode> {
    syd::set_sigpipe_dfl()?;

    // Configure syd::proc.
    syd::config::proc_init()?;

    let pid = match std::env::args().nth(1).map(|arg| arg.parse::<pid_t>()) {
        Some(Ok(pid)) => pid,
        None => Pid::this().as_raw(),
        Some(Err(_)) => {
            help();
            return Ok(ExitCode::SUCCESS);
        }
    };

    let stat = proc_stat(Pid::from_raw(pid))?;
    let status = proc_status(Pid::from_raw(pid))?;
    #[allow(clippy::disallowed_methods)]
    let status = json!({
        "pid": pid,
        "tgid": status.pid,
        "command": status.command,
        "umask": status.umask,
        "tty_nr": stat.tty_nr,
        "startstack": stat.startstack,
        "num_threads": stat.num_threads,
        "sig": {
            "blocked": status.sig_blocked,
            "caught": status.sig_caught,
            "ignored": status.sig_ignored,
            "pending_thread": status.sig_pending_thread,
            "pending_process": status.sig_pending_process,
        },
    });

    #[allow(clippy::disallowed_methods)]
    let status = serde_json::to_string_pretty(&status).unwrap();
    println!("{status}");

    Ok(ExitCode::SUCCESS)
}

fn help() {
    println!("Usage: syd-stat [PID]");
    println!("Print detailed information about the given process process or current process.");
}
