/*
 * libsysactivity
 * http://sourceforge.net/projects/libsysactivity/
 * Copyright (c) 2009, 2010 Carlos Olmedo Escobar <carlos.olmedo.e@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

/**
 * \defgroup process Process interface
 * @{
 */
#ifndef SA_PROCESS_H_
#define SA_PROCESS_H_

#include <sys/types.h>

/** \enum sa_process_state
 * The different types of states of a process.
 */
enum sa_process_state {
	SA_UNKNOWN = 0, //!< The state is unknown.
	SA_RUNNING = 1, //!< The process is running.
	SA_SLEEPING = 2, //!< The process is sleeping.
	SA_SLEEPING_UNINTERRUPTIBLE = 3, //!< The process is an uninterruptible sleep
	SA_ZOMBIE = 4, //!< It has completed execution but still has an entry in the process table.
	SA_STOPPED = 5, //!< The process is traced or stopped.
};

/** \struct sa_process_activity process.h
 * This structure holds the information of the activity of a process.
 */
struct sa_process_activity {
#ifdef SA_PROCESS_PID
	pid_t pid; //!< The id of the process
#endif
#ifdef SA_PROCESS_STATE
	enum sa_process_state state; //!< The current state of the process.
#endif
#ifdef SA_PROCESS_USER_TIME // TODO Explain these better
	uint64_t user_time; //!< User mode jiffies
#endif
#ifdef SA_PROCESS_SYS_TIME
	uint64_t sys_time; //!< Kernel mode jiffies
#endif
#ifdef SA_PROCESS_THREADS
	uint32_t threads; //!< Number of threads
#endif
#ifdef SA_PROCESS_VM_SIZE
	uint32_t vm_size; //!< Virtual memory size
#endif
#ifdef SA_PROCESS_RSS
	uint32_t rss; //!< Resident Set memory Size
#endif
};

/** \struct sa_process process.h
 * This structure holds the static information about a process.
 */
struct sa_process {
#ifdef SA_PROCESS_PID
	pid_t pid; //!< The id of the process
#endif
#ifdef SA_PROCESS_UID
	uid_t uid; //!< The id of the user running this process
#endif
#ifdef SA_PROCESS_GID
	gid_t gid; //!< Id of the user's group running this process
#endif
#ifdef SA_PROCESS_FILENAME
	char filename[SA_PROCESS_FILENAME]; //!< The name of the running file.
#endif
#ifdef SA_PROCESS_CMDLINE
	char cmdline[SA_PROCESS_CMDLINE]; //!< The command executed to launch this process.
#endif
#ifdef SA_PROCESS_PARENT_PID
	pid_t parent_pid; //!< The id of its parent
#endif
#ifdef SA_PROCESS_PGRP
	pid_t pgrp; //!< The group id the process
#endif
#ifdef SA_PROCESS_SID
	pid_t sid; //!< Session id of this process
#endif
#ifdef SA_PROCESS_TTY
	pid_t tty; //!< The id of the tty this process is running on.
#endif
#ifdef SA_PROCESS_NICE
	int8_t nice; //!< Priority of this process.
#endif
#ifdef SA_PROCESS_START_TIME
	uint64_t start_time; //!< Process start time in hundredths of second since system boot
#endif
struct sa_process_activity activity;
};

#ifdef SA_OPEN_PROCESS
/**
 * Prepares the resources needed for retrieving process statistics. This function exists (and is needed) only when SA_OPEN_PROCESS is defined.
 * @return If successful 0 is returned, otherwise an error code is returned. If the operating system is not supported the return value will be ENOTSUP.
 * @see sa_close_process()
 */
int sa_open_process() SA_EXPORT;
#endif

#ifdef SA_CLOSE_PROCESS
/**
 * This function closes the resources used for retrieving process statistics. You should call it even when there was a previous error in another function of this API. This function exists (and is needed) only when SA_CLOSE_PROCESS is defined.
 * @return If successful 0 is returned, otherwise an error code is returned.
 * @see sa_open_process()
 */
int sa_close_process() SA_EXPORT;
#endif

/**
 * Gives the total number of processes on the systems.
 * @param number The number will be stored here
 * @return If successful 0 is returned, otherwise an error code is returned.
 */
int sa_count_processes(uint32_t* number) SA_EXPORT SA_NONNULL;

/**
 * Gets a list of the existing processes ids. The array will be fully populated even if it's not big enough (but ENOMEM is returned).
 * @param dst A pointer to the array to populate.
 * @param dst_size The number of pid_t that fits in the array.
 * @param written The number of pids written is stored here.
 * @return If successful 0 is returned, otherwise an error code is returned.
 * @since 0.4.1
 */
int sa_get_processes_ids(pid_t* dst, uint32_t dst_size, uint32_t* written) SA_EXPORT SA_NONNULL;

/**
 * Retrieves statistics from a process identified by its pid.
 * @param pid The pid of the process.
 * @param dst Where the statistics will be stored.
 * @return If successful 0 is returned, otherwise an error code is returned. ESRCH is returned if the requested process was not found.
 */
int sa_get_process(pid_t pid, struct sa_process* dst) SA_EXPORT SA_NONNULL;

/**
 * Retrieves the activity of a process on the dst parameter.
 * @param pid The pid of the process.
 * @param dst Where the statistics will be stored.
 * @return If successful 0 is returned, otherwise an error code is returned. ESRCH is returned if the requested process was not found.
 * @since 0.6.0
 */
int sa_get_process_activity(pid_t pid, struct sa_process_activity* dst) SA_EXPORT SA_NONNULL;

/*@}*/
#endif /* SA_PROCESS_H_ */
