/*
 * Copyright (C) 2011-2012 Red Hat, Inc.
 *
 * This file is part of LVM2.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU Lesser General Public License v.2.1.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#ifndef _LVM_DAEMON_SERVER_H
#define _LVM_DAEMON_SERVER_H

#include "daemon-client.h"

typedef struct {
	int socket_fd; /* the fd we use to talk to the client */
	pthread_t thread_id;
	char *read_buf;
	void *private; /* this holds per-client state */
} client_handle;

typedef struct {
	struct dm_config_tree *cft;
	struct buffer buffer;
} request;

typedef struct {
	int error;
	struct dm_config_tree *cft;
	struct buffer buffer;
} response;

struct timeval;

/*
 * is_idle:	 daemon implementation sets it to true when no background task
 *		 is running
 * max_timeouts: how many seconds do daemon allow to be idle before it shutdowns
 * ptimeout:	 internal variable passed to select(). has to be reset to 1 second
 *		 before each select
 */
typedef struct {
	volatile unsigned is_idle;
	unsigned max_timeouts;
	struct timeval *ptimeout;
} daemon_idle;

struct daemon_state;

/*
 * Craft a simple reply, without the need to construct a config_tree. See
 * daemon_send_simple in daemon-client.h for the description of the parameters.
 */
response daemon_reply_simple(const char *id, ...);

static inline int daemon_request_int(request r, const char *path, int def) {
	if (!r.cft)
		return def;
	return dm_config_find_int(r.cft->root, path, def);
}

static inline const char *daemon_request_str(request r, const char *path, const char *def) {
	if (!r.cft)
		return def;
	return dm_config_find_str(r.cft->root, path, def);
}

/*
 * The callback. Called once per request issued, in the respective client's
 * thread. It is presented by a parsed request (in the form of a config tree).
 * The output is a new config tree that is serialised and sent back to the
 * client. The client blocks until the request processing is done and reply is
 * sent.
 */
typedef response (*handle_request)(struct daemon_state s, client_handle h, request r);

typedef struct {
	uint32_t log_config[32];
	void *backend_state[32];
	const char *name;
} log_state;

struct thread_state;

typedef struct daemon_state {
	/*
	 * The maximal stack size for individual daemon threads. This is
	 * essential for daemons that need to be locked into memory, since
	 * pthread's default is 10M per thread.
	 */
	int thread_stack_size;

	/* Flags & attributes affecting the behaviour of the daemon. */
	unsigned avoid_oom:1;
	unsigned foreground:1;
	const char *name;
	const char *pidfile;
	const char *socket_path;
	const char *protocol;
	int protocol_version;

	handle_request handler;
	int (*daemon_init)(struct daemon_state *st);
	int (*daemon_fini)(struct daemon_state *st);
	int (*daemon_main)(struct daemon_state *st);

	/* Global runtime info maintained by the framework. */
	int socket_fd;

	log_state *log;
	struct thread_state *threads;

	/* suport for shutdown on idle */
	daemon_idle *idle;

	void *private; /* the global daemon state */
} daemon_state;

typedef struct thread_state {
	daemon_state s;
	client_handle client;
	struct thread_state *next;
	volatile int active;
} thread_state;

/*
 * Start serving the requests. This does all the daemonisation, socket setup
 * work and so on. This function takes over the process, and upon failure, it
 * will terminate execution. It may be called at most once.
 */
void daemon_start(daemon_state s);

/*
 * Take over from an already running daemon. This function handles connecting
 * to the running daemon and telling it we are going to take over. The takeover
 * request may be customised by passing in a non-NULL request.
 *
 * The takeover sequence: the old daemon stops accepting new clients, then it
 * waits until all current client connections are closed. When that happens, it
 * serializes its current state and sends that as a reply, which is then
 * returned by this function (therefore, this function won't return until the
 * previous instance has shut down).
 *
 * The daemon, after calling daemon_takeover is expected to set up its
 * daemon_state using the reply from this function and call daemon_start as
 * usual.
 */
daemon_reply daemon_takeover(daemon_info i, daemon_request r);

/* Call this to request a clean shutdown of the daemon. Async safe. */
void daemon_stop(void);

enum { DAEMON_LOG_OUTLET_SYSLOG = 1,
       DAEMON_LOG_OUTLET_STDERR = 2,
       DAEMON_LOG_OUTLET_SOCKET = 4 };

/* Log a message of a given type. */
void daemon_log(log_state *s, int type, const char *message);

/* Log a config (sub)tree, using a given message type, each line prefixed with "prefix". */
void daemon_log_cft(log_state *s, int type, const char *prefix,
                    const struct dm_config_node *n);

/* Log a multi-line block, prefixing each line with "prefix". */
void daemon_log_multi(log_state *s, int type, const char *prefix, const char *message);

/* Log a formatted message as "type". See also daemon-log.h. */
void daemon_logf(log_state *s, int type, const char *format, ...)
	__attribute__ ((format(printf, 3, 4)));

/*
 * Configure log_state to send messages of type "type" to the log outlet
 * "outlet", iff "enable" is true.
 */
void daemon_log_enable(log_state *s, int outlet, int type, int enable);

/*
 * Set up logging on a given outlet using a list of message types (comma
 * separated) to log using that outlet. The list is expected to look like this,
 * "all,wire,debug". Returns 0 upon encountering an unknown message type.
 */
int daemon_log_parse(log_state *s, int outlet, const char *types, int enable);

#endif
