/*
 *
 *  Connection Manager
 *
 *  Copyright (C) 2007-2009  Intel Corporation. All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <unistd.h>
#include <sys/wait.h>

#include <glib.h>

#include <connman/log.h>

#include "task.h"

#define	_DBG_TASK(fmt, arg...)	DBG(DBG_TASK, fmt, ## arg)

struct task_data {
	pid_t pid;
	int index;
	task_cb_t callback;
	void *user_data;
};

static GSList *task_list = NULL;

struct task_data *task_find_by_pid(pid_t pid)
{
	GSList *list;

	for (list = task_list; list; list = list->next) {
		struct task_data *task = list->data;

		if (task->pid == pid)
			return task;
	}

	return NULL;
}

struct task_data *task_find_by_index(int index)
{
	GSList *list;

	for (list = task_list; list; list = list->next) {
		struct task_data *task = list->data;

		if (task->index == index)
			return task;
	}

	return NULL;
}

static void task_died(GPid pid, gint status, gpointer user_data)
{
	struct task_data *task = user_data;

	if (WIFEXITED(status))
		_DBG_TASK("task %p exit status %d", task, WEXITSTATUS(status));
	else
		_DBG_TASK("task %p signal %d", task, WTERMSIG(status));

	g_spawn_close_pid(pid);
	task->pid = 0;

	task_list = g_slist_remove(task_list, task);

	if (task->callback)
		task->callback(task->index, task->user_data);

	g_free(task);
}

static void task_setup(gpointer user_data)
{
	struct task_data *task = user_data;

	_DBG_TASK("task %p", task);
}

struct task_data *task_spawn(int index, char **argv, char **envp,
					task_cb_t callback, void *user_data)
{
	GSpawnFlags flags = G_SPAWN_DO_NOT_REAP_CHILD |
						G_SPAWN_STDOUT_TO_DEV_NULL;
	struct task_data *task;

	_DBG_TASK("index %d", index);

	task = g_try_new0(struct task_data, 1);
	if (task == NULL)
		return NULL;

	task->index = index;

	task->callback  = callback;
	task->user_data = user_data;

	if (g_spawn_async(NULL, argv, envp, flags,
				task_setup, task, &task->pid, NULL) == FALSE) {
		connman_error("Failed to spawn task");
		return NULL;
	}

	task_list = g_slist_append(task_list, task);

	g_child_watch_add(task->pid, task_died, task);

	_DBG_TASK("task %p pid %d", task, task->pid);

	return task;
}

int task_kill(struct task_data *task)
{
	_DBG_TASK("task %p", task);

	if (task->pid > 0)
		kill(task->pid, SIGTERM);

	return 0;
}

void *task_get_data(struct task_data *task)
{
	return task->user_data;
}
