/*
 * Created by hongbo.he@lnxall.com
 *
 * 2025/09/02
 */
#ifndef LNXUTILS_BASH_H
#define LNXUTILS_BASH_H
#include <stddef.h>
#include <signal.h>
#include <stdint.h>

/*
 * execute shell command
 *
 * DESCRIPTION
 *	timeout: 
 *	 the unit is second
 *	 if timeout <= 0, command will be blocked until it exit
 *
 *  set the outbuf or outlen null to discard the result of command execution
 *
 * RETURN VALUE
 *  if success, return size of command result (>= 0)
 *		the size may over than outlen. it indicates the actual result length received from cmdsvr-udp
 *  while error occurrd, return -1 and set the errno
 *
 * ERRORS
 *  EMSGSIZE:
 *  if outbuf is smaller than output of command, errno will be set to this
 *   and message will be truncated.
 *
 */
int lnxutil_command_reply(const char *cmd, char *outbuf, size_t outlen, int timeout);

/*
 * get name of current exec
 *	@Author: jiaqiang.ye@lnxall.com
 *
 * RETURN VALUE
 *  if success, return bytes of name
 *  when error occurrd, return a negative value
 *
 */
int lnxall_exename(char * out, int outlen);

/*
 * get pid by proc name: /proc/<PID>/comm
 *  equals to `lnxutil_getpid2(const char *name, GP_FIRST)
 *
 * RETURN VALUE
 *  if return -1, indicates no pid found in system
 *  else return its pid
 *
 */
pid_t lnxutil_getpid(const char *name);

#define GP_FIRST        0x0000
#define GP_LAST         0x0001
#define GP_EXCLUDE_SELF 0x0002
#define GP_UNIQUE       0x0004

/*
 * get pid by proc name with flags: /proc/<PID>/comm
 *
 * FLAGS
 *  GP_FIRST:
 *		return first matched pid
 *  GP_LAST:
 *		return last matched pid
 *  GP_EXCLUDE_SELF:
 *		exclude current process
 *  GP_UNIQUE:
 *		return -1 and set errno to EEXIST when more than one pid is found
 *
 * NOTES
 *  the combination `GP_UNIQUE | GP_LAST` is prone to sematic confusion,
 *   therefore considered an illegal combination
 *
 * RETURN VALUE
 *  if return -1, indicates no pid found or error occurred
 *  else return its pid
 *
 */
pid_t lnxutil_getpid2(const char *name, unsigned int flags);

/*
 * get memory, cpu usage
 *
 * RETURN VALUE
 *	if successfully got, return 0
 *	while some error occurrd, return -1 and set the errno
 *
 * WARNNING
 *  get cpu usage will block for 1 second
 *
 */
struct lnxutil_meminfo {
	/* unit: kB */
	unsigned long	mem_total;
	unsigned long	mem_free;
	unsigned long	mem_available;
};

int lnxutil_meminfo(struct lnxutil_meminfo *info);

int lnxutil_mem_usage(double *usage);

int lnxutil_cpu_usage(double *usage);

double lnxutil_cpu_usage2(uint32_t interval);

/*
 * set system language: en_US.UTF-8 zh_CN.UTF-8 ...
 * if no explicit encoding format, just `en_US `zh_CN, set UTF-8 as default
 *
 * RETURN VALUE
 *  0 indicates success, return -1 shows argument may be illegal
 *
 */
int lnxutil_set_syslang(const char *la);

#endif
