/*
 *  stpgd_main.c
 */

#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <malloc.h>
#include <inttypes.h>
#include <sys/wait.h>
#include <poll.h>
#include <sys/ioctl.h>
#include <stdbool.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <syslog.h>
#include <signal.h>
#include <syslog.h>

#include "version.h"
#include "debug.h"
#include "scst_event.h"

char *app_name;

#define DEFAULT_TRANSITION_TIME 17

#if defined(DEBUG) || defined(TRACING)

#ifdef DEBUG

#define DEFAULT_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MINOR | TRACE_PID | \
	TRACE_FUNCTION | TRACE_SPECIAL | TRACE_MGMT | TRACE_MGMT_DEBUG | \
	TRACE_TIME)

#define TRACE_SN(args...)	TRACE(TRACE_SCSI_SERIALIZING, args)

#else /* DEBUG */

# ifdef TRACING
#define DEFAULT_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MGMT | \
	TRACE_TIME | TRACE_SPECIAL)
# else
#define DEFAULT_LOG_FLAGS 0
# endif
#endif /* DEBUG */

unsigned long trace_flag = DEFAULT_LOG_FLAGS;
#endif /* defined(DEBUG) || defined(TRACING) */

#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))

bool log_daemon = true;
int transition_timeout = DEFAULT_TRANSITION_TIME;

static struct option const long_options[] = {
	{"path", required_argument, 0, 'p'},
	{"timeout", required_argument, 0, 't'},
	{"foreground", no_argument, 0, 'f'},
#if defined(DEBUG) || defined(TRACING)
	{"debug", required_argument, 0, 'd'},
#endif
	{"version", no_argument, 0, 'v'},
	{"help", no_argument, 0, 'h'},
	{0, 0, 0, 0},
};

int stpg_init_report_pipe[2];
char *stpg_path;

static void usage(int status)
{
	if (status != 0)
		fprintf(stderr, "Try '%s --help' for more information.\n", app_name);
	else {
		printf("Usage: %s [OPTIONS]\n", app_name);
		printf("STPG target daemon\n");
		printf("  -f, --foreground	make the program run in the foreground\n");
		printf("  -p, --path		absolute path to the STPG script\n");
		printf("  -t, --timeout		transition timeout\n");
#if defined(DEBUG) || defined(TRACING)
		printf("  -d, --debug=level     debug tracing level\n");
#endif
		printf("  -h, --help		display this help and exit\n");
	}
}

static void stpg_handle_tm_received(struct scst_event_user *event_user)
{
	/*
	 * Put code to abort state transition here, if this STPG cmd,
	 * identified by cmd_to_abort_tag or RESET, requested to be aborted
	 */
}

static int invoke_stpg(const uint8_t *device_name,
	const struct scst_event_stpg_descr *descr, pid_t *out_pid)
{
	char *args[7], *env[7];
	int res = 0, ret, i;
	pid_t c_pid;

	args[0] = stpg_path;
	args[1] = (char *)device_name;
	args[2] = (char *)descr->prev_state;
	args[3] = (char *)descr->new_state;
	args[4] = (char *)descr->dg_name;
	args[5] = (char *)descr->tg_name;
	args[6] = NULL;

	env[0] = "PATH=/bin:/usr/bin:/sbin:/usr/sbin";
	ret = asprintf(&env[1], "SCST_DEVICE_NAME=%s", device_name);
	if (ret < 0) {
		res = -errno;
		PRINT_ERROR("asprintf() failed: %d (%s)", res, strerror(-res));
		goto out;
	}
	ret = asprintf(&env[2], "SCST_PREV_ALUA_STATE=%s", descr->prev_state);
	if (ret < 0) {
		res = -errno;
		PRINT_ERROR("asprintf() failed: %d (%s)", res, strerror(-res));
		goto out;
	}
	ret = asprintf(&env[3], "SCST_ALUA_STATE=%s", descr->new_state);
	if (ret < 0) {
		res = -errno;
		PRINT_ERROR("asprintf() failed: %d (%s)", res, strerror(-res));
		goto out;
	}
	ret = asprintf(&env[4], "SCST_DEVICE_GROUP=%s", descr->dg_name);
	if (ret < 0) {
		res = -errno;
		PRINT_ERROR("asprintf() failed: %d (%s)", res, strerror(-res));
		goto out;
	}
	ret = asprintf(&env[5], "SCST_TARGET_GROUP=%s", descr->tg_name);
	if (ret < 0) {
		res = -errno;
		PRINT_ERROR("asprintf() failed: %d (%s)", res, strerror(-res));
		goto out;
	}
	env[6] = NULL;

	PRINT_INFO("Invoking script %s with parameters: %s %s %s %s %s and environment: "
		"%s %s %s %s %s", stpg_path, args[1], args[2], args[3],
		args[4], args[5], env[1], env[2], env[3], env[4], env[5]);

	c_pid = fork();
	if (c_pid == 0) {
		ret = setpgid(getpid(), getpid());
		if (ret < 0) {
			res = -errno;
			PRINT_ERROR("setgid failed %d (%s)", ret, strerror(-ret));
		}
		TRACE_DBG("pgid %d (pid %d)", getpgid(getpid()), getpid());
		ret = execve(stpg_path, args, env);
		if (ret < 0) {
			res = -errno;
			PRINT_ERROR("EXEC failed %d (%s)", ret, strerror(-ret));
		}
		exit(0);
	} else if (c_pid < 0) {
		res = -errno;
		PRINT_ERROR("fork() failed: %d (%s)", res, strerror(-res));
	}

	*out_pid = c_pid;

	for (i = 1; i < (signed)ARRAY_SIZE(env); i++)
		free(env[i]);

out:
	return res;
}

/* Returns 0, if the pid is still running, >0 if it was exited or <0 error code */
static int wait_until_finished(pid_t pid, unsigned long deadline, int *status, int child)
{
	int res;
	time_t start, end;
	double elapsed;

	TRACE_ENTRY();

	time(&start);
	do {
		res = waitpid(pid, status, WNOHANG);
		if (res != 0) {
			if (res < 0) {
				res = -errno;
				PRINT_ERROR("Waitpid for pid %d (child %d) "
					"failed: %d (%s)", pid, child,
					errno, strerror(errno));
			}
			break;
		}
		usleep(100*1000);
		time(&end);
		elapsed = difftime(end, start);
	} while (elapsed < deadline);

	TRACE_EXIT_RES(res);
	return res;
}

static int handle_stpg_received(struct scst_event_user *event_user)
{
	const struct scst_event_stpg_payload *p = (struct scst_event_stpg_payload *)event_user->out_event.payload;
	int num, k;
	int res = 0;
	pid_t pids[p->stpg_descriptors_cnt];

	TRACE_DBG("device name %s, stpg_descriptors_cnt %d", p->device_name,
		p->stpg_descriptors_cnt);

	for (num = 0; num < p->stpg_descriptors_cnt; num++) {
		res = invoke_stpg(p->device_name, &p->stpg_descriptors[num], &pids[num]);
		TRACE_DBG("num %d, res %d, pid %d", num, res, pids[num]);
		if (res != 0)
			break;
	}

	TRACE_DBG("num %d", num);
	for (k = 0; k < num; k++) {
		int status = 0, rc;

		TRACE_DBG("k %d, pid %d", k, pids[k]);

		rc = wait_until_finished(pids[k], transition_timeout, &status, k);
		TRACE_DBG("rc %d, status %d", rc, WEXITSTATUS(status));
		if (rc > 0) {
			if (res == 0)
				res = WEXITSTATUS(status);
			continue;
		} else if (rc < 0) {
			if (res == 0)
				res = rc;
			continue;
		}

		PRINT_WARNING("on_stpg %d (pid %d) did not finish on time - "
			"sending SIGTERM", k, pids[k]);
		if (res == 0)
			res = -ETIMEDOUT;
		rc = killpg(pids[k], SIGTERM);
		if (rc < 0)
			PRINT_ERROR("Failed to send SIGTERM to child %d (pid %d): %d/%s",
				k, pids[k], errno, strerror(errno));

		rc = wait_until_finished(pids[k], 1, &status, k);
		if (rc != 0)
			continue;

		while (1) {
			PRINT_WARNING("on_stpg %d (pid %d) did not finish on time - "
					"sending SIGKILL", k, pids[k]);
			rc = killpg(pids[k], SIGKILL);
			if (rc < 0) {
				PRINT_ERROR("Failed to send SIGKILL to child %d "
					"(pid %d): %d/%s", k, pids[k], errno,
					strerror(errno));
				break;
			}
			rc = wait_until_finished(pids[k], 1, &status, k);
			if (rc != 0)
				break;
		};
	}

	TRACE_EXIT_RES(res);
	return res;
}

static int stpg_event_loop(void)
{
	int res = 0, status;
	int event_fd;
	uint8_t event_user_buf[1024*1024];
	pid_t c_pid = 0;
	struct pollfd pl;
	struct scst_event_user *event_user =
		(struct scst_event_user *)event_user_buf;
	struct scst_event e1;
	bool first_error = true;

	event_fd = open(SCST_EVENT_DEV, O_RDWR);
	if (event_fd < 0) {
		res = -errno;
		PRINT_ERROR("Unable to open SCST event device %s (%s)",
			SCST_EVENT_DEV, strerror(-res));
		goto out;
	}

	close(stpg_init_report_pipe[0]);

	if (log_daemon)
		res = write(stpg_init_report_pipe[1], &res, sizeof(res));

	close(stpg_init_report_pipe[1]);

	memset(&pl, 0, sizeof(pl));
	pl.fd = event_fd;
	pl.events = POLLIN;

	memset(&e1, 0, sizeof(e1));
	e1.event_code = SCST_EVENT_STPG_USER_INVOKE;
	strncpy(e1.issuer_name, SCST_EVENT_SCST_CORE_ISSUER,
		sizeof(e1.issuer_name));
	e1.issuer_name[sizeof(e1.issuer_name)-1] = '\0';
	PRINT_INFO("Setting allowed event code %d, issuer_name %s",
		   e1.event_code, e1.issuer_name);

	res = ioctl(event_fd, SCST_EVENT_ALLOW_EVENT, &e1);
	if (res != 0) {
		res = -errno;
		PRINT_ERROR("SCST_EVENT_ALLOW_EVENT failed: %d (%s)",
			    res, strerror(-res));
		goto out;
	}

	e1.event_code = SCST_EVENT_TM_FN_RECEIVED;
	strncpy(e1.issuer_name, SCST_EVENT_SCST_CORE_ISSUER,
		sizeof(e1.issuer_name));
	e1.issuer_name[sizeof(e1.issuer_name)-1] = '\0';
	PRINT_INFO("Setting allowed event code %d, issuer_name %s",
		   e1.event_code, e1.issuer_name);
	res = ioctl(event_fd, SCST_EVENT_ALLOW_EVENT, &e1);
	if (res != 0) {
		res = -errno;
		PRINT_ERROR("SCST_EVENT_ALLOW_EVENT failed: %d (%s)",
			    res, strerror(-res));
		goto out;
	}

	while (1) {
		memset(event_user_buf, 0, sizeof(event_user_buf));
		event_user->max_event_size = sizeof(event_user_buf);
		res = ioctl(event_fd, SCST_EVENT_GET_NEXT_EVENT, event_user);
		if (res != 0) {
			res = -errno;
			switch (-res) {
			case ESRCH:
			case EBUSY:
				TRACE_MGMT_DBG("SCST_EVENT_GET_NEXT_EVENT "
					"returned %d (%s)", res, strerror(res));
				/* fall through */
			case EINTR:
				continue;
			case EAGAIN:
				TRACE_DBG("SCST_EVENT_GET_NEXT_EVENT, "
					"returned EAGAIN (%d)", -res);
				continue;
			default:
				PRINT_ERROR("SCST_EVENT_GET_NEXT_EVENT "
					"failed: %d (%s)", res, strerror(-res));
				if (!first_error)
					goto out;
				first_error = false;
				continue;
			}
			first_error = true;
again_poll:
			res = poll(&pl, 1, c_pid > 0 ? 1 : 0);
			if (res > 0)
				continue;
			else if (res == 0)
				goto again_poll;
			else {
				res = -errno;
				switch (res) {
				case ESRCH:
				case EBUSY:
				case EAGAIN:
					TRACE_MGMT_DBG("poll() returned %d "
						"(%s)", res, strerror(-res));
				case EINTR:
					goto again_poll;
				default:
					PRINT_ERROR("poll() failed: %d (%s)",
						res, strerror(-res));
					goto again_poll;
				}
			}
		}
		first_error = true;
#ifdef DEBUG
		PRINT_INFO("event_code %d, issuer_name %s",
			event_user->out_event.event_code,
			event_user->out_event.issuer_name);
#endif
		if (event_user->out_event.payload_len != 0)
			TRACE_BUFFER("payload", event_user->out_event.payload,
				event_user->out_event.payload_len);

		if (event_user->out_event.event_code == SCST_EVENT_STPG_USER_INVOKE) {
			c_pid = fork();
			if (c_pid == -1)
				PRINT_ERROR("Failed to fork: %d", c_pid);
			else if (c_pid == 0) {
				struct scst_event_notify_done d;

				signal(SIGCHLD, SIG_DFL);

				status = handle_stpg_received(event_user);

				memset(&d, 0, sizeof(d));
				d.event_id = event_user->out_event.event_id;
				d.status = status;
				res = ioctl(event_fd, SCST_EVENT_NOTIFY_DONE, &d);
				if (res != 0) {
					res = -errno;
					PRINT_ERROR("SCST_EVENT_NOTIFY_DONE "
						"failed: %s (res %d)",
						strerror(-res), res);
				} else
					PRINT_INFO("STPG event completed with status %d", status);
				exit(res);
			}
		} else if (event_user->out_event.event_code == SCST_EVENT_TM_FN_RECEIVED)
			stpg_handle_tm_received(event_user);
		else
			PRINT_ERROR("Unknown event %d received", event_user->out_event.event_code);
	}
out:
	return res;
}

static void sig_chld(int signal)
{
	/* Check just in case */
	if (signal == SIGCHLD) {
		TRACE_DBG("Cleanup zombie (pid %d)", getpid());
		wait(NULL);
	}
}

int main(int argc, char **argv)
{
	int res = 0, ch, longindex;
	pid_t pid;
	struct sigaction sa;

	setlinebuf(stdout);

	openlog(argv[0], LOG_PID, LOG_USER);

	res = pipe(stpg_init_report_pipe);
	if (res == -1) {
		res = -errno;
		PRINT_ERROR("Pipe failed: %d (%s)", res, strerror(-res));
		goto out;
	}

	sa.sa_handler = &sig_chld;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
	if (sigaction(SIGCHLD, &sa, 0) == -1) {
		PRINT_ERROR("sigaction() failed: %d/%s", errno, strerror(errno));
		exit(1);
	}

	/*
	 * Otherwise we could die in some later write() during the event_loop()
	 * instead of getting EPIPE!
	 */
	signal(SIGPIPE, SIG_IGN);

	res = debug_init();
	if (res != 0)
		goto out;

	app_name = argv[0];

	while ((ch = getopt_long(argc, argv, "+d:fp:t:hv",
			long_options, &longindex)) >= 0) {
		switch (ch) {
		case 'p':
			stpg_path = optarg;
			break;
#if defined(DEBUG) || defined(TRACING)
		case 'd':
		       trace_flag = strtol(optarg, (char **)NULL, 0);
		       break;
#endif
		case 'v':
			printf("%s version %s\n", app_name, VERSION_STR);
			goto out_done;
		case 'f':
			log_daemon = false;
			break;
		case 't':
			transition_timeout = strtol(optarg, (char **)NULL, 0);
			if (transition_timeout < 0) {
				printf("Invalid timeout %d\n", transition_timeout);
				res = -EINVAL;
				goto out_done;
			}
			break;
		case 'h':
			usage(0);
			goto out_done;
		default:
			goto out_usage;
		}
	}

	if (!stpg_path)
		stpg_path = "/usr/local/bin/scst/scst_on_stpg";

	if (access(stpg_path, X_OK) == -1) {
		PRINT_ERROR("Script file \" %s \"does not exist or not "
			"executable", stpg_path);
		res = -1;
		goto out_done;
	}

#ifdef DEBUG
	PRINT_INFO("trace_flag %lx", trace_flag);
#endif
	if (log_daemon) {
#if defined(DEBUG) || defined(TRACING)
		trace_flag &= ~TRACE_TIME;
		trace_flag &= ~TRACE_PID;
#endif

		pid = fork();
		if (pid < 0) {
			PRINT_ERROR("starting daemon failed(%d)", pid);
			res = pid;
			goto out_done;
		} else if (pid) {
			int res1 = -1;

			close(stpg_init_report_pipe[1]);
			if ((unsigned)read(stpg_init_report_pipe[0], &res1, sizeof(res1)) < sizeof(res1)) {
				res = -1;
				goto out_done;
			} else {
				res = res1;
				goto out_done;
			}
		}

		close(0);
		open("/dev/null", O_RDWR);
		dup2(0, 1);
		dup2(0, 2);
		setsid();
	}

	res = stpg_event_loop();

out_done:
	debug_done();

out:
	closelog();
	return res;

out_usage:
	usage(1);
	goto out_done;
}
