/*
 * Copyright (C) 2011-2019 Tobias Brunner
 * Copyright (C) 2007-2011 Martin Willi
 * Copyright (C) 2011 revosec AG
 * HSR Hochschule fuer Technik Rapperswil
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
 *
 * 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.
 */

#include "controller.h"

#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>

#include <daemon.h>
#include <library.h>
#include <threading/thread.h>
#include <threading/spinlock.h>
#include <threading/semaphore.h>

typedef struct private_controller_t private_controller_t;
typedef struct interface_listener_t interface_listener_t;
typedef struct interface_logger_t interface_logger_t;

/**
 * Private data of an stroke_t object.
 */
struct private_controller_t {

	/**
	 * Public part of stroke_t object.
	 */
	controller_t public;
};

/**
 * helper struct for the logger interface
 */
struct interface_logger_t {
	/**
	 * public logger interface
	 */
	logger_t public;

	/**
	 * reference to the listener
	 */
	interface_listener_t *listener;

	/**
	 *  interface callback (listener gets redirected to here)
	 */
	controller_cb_t callback;

	/**
	 * user parameter to pass to callback
	 */
	void *param;
};

/**
 * helper struct to map listener callbacks to interface callbacks
 */
struct interface_listener_t {

	/**
	 * public bus listener interface
	 */
	listener_t public;

	/**
	 * logger interface
	 */
	interface_logger_t logger;

	/**
	 * status of the operation, return to method callers
	 */
	status_t status;

	/**
	 * child configuration, used for initiate
	 */
	child_cfg_t *child_cfg;

	/**
	 * peer configuration, used for initiate
	 */
	peer_cfg_t *peer_cfg;

	/**
	 * IKE_SA to handle
	 */
	ike_sa_t *ike_sa;

	/**
	 * unique ID, used for various methods
	 */
	uint32_t id;

	/**
	 * semaphore to implement wait_for_listener()
	 */
	semaphore_t *done;

	/**
	 * spinlock to update the IKE_SA handle properly
	 */
	spinlock_t *lock;

	union {
		/**
		 * whether to check limits during initiation
		 */
		bool limits;

		/**
		 * whether to force termination
		 */
		bool force;
	} options;
};


typedef struct interface_job_t interface_job_t;

/**
 * job for asynchronous listen operations
 */
struct interface_job_t {

	/**
	 * job interface
	 */
	job_t public;

	/**
	 * associated listener
	 */
	interface_listener_t listener;

	/**
	 * the job is reference counted as the thread executing a job as well as
	 * the thread waiting in wait_for_listener() require it but either of them
	 * could be done first
	 */
	refcount_t refcount;
};

/**
 * This function wakes a thread that is waiting in wait_for_listener(),
 * either from a listener or from a job.
 */
static inline bool listener_done(interface_listener_t *listener)
{
	if (listener->done)
	{
		listener->done->post(listener->done);
	}
	return FALSE;
}

/**
 * thread_cleanup_t handler to unregister a listener.
 */
static void listener_unregister(interface_listener_t *listener)
{
	charon->bus->remove_listener(charon->bus, &listener->public);
	charon->bus->remove_logger(charon->bus, &listener->logger.public);
}

/**
 * Registers the listener, executes the job and then waits synchronously until
 * the listener is done or the timeout occurred.
 *
 * @note Use 'return listener_done(listener)' to properly unregister a listener
 *
 * @param listener  listener to register
 * @param job       job to execute asynchronously when registered, or NULL
 * @param timeout   max timeout in ms to listen for events, 0 to disable
 * @return          TRUE if timed out
 */
static bool wait_for_listener(interface_job_t *job, u_int timeout)
{
	interface_listener_t *listener = &job->listener;
	bool old, timed_out = FALSE;

	/* avoid that the job is destroyed too early */
	ref_get(&job->refcount);

	listener->done = semaphore_create(0);

	charon->bus->add_logger(charon->bus, &listener->logger.public);
	charon->bus->add_listener(charon->bus, &listener->public);
	lib->processor->queue_job(lib->processor, &job->public);

	thread_cleanup_push((thread_cleanup_t)listener_unregister, listener);
	old = thread_cancelability(TRUE);
	if (timeout)
	{
		timed_out = listener->done->timed_wait(listener->done, timeout);
	}
	else
	{
		listener->done->wait(listener->done);
	}
	thread_cancelability(old);
	thread_cleanup_pop(TRUE);
	return timed_out;
}

METHOD(logger_t, listener_log, void,
	interface_logger_t *this, debug_t group, level_t level, int thread,
	ike_sa_t *ike_sa, const char *message)
{
	ike_sa_t *target;

	this->listener->lock->lock(this->listener->lock);
	target = this->listener->ike_sa;
	this->listener->lock->unlock(this->listener->lock);

	if (target == ike_sa)
	{
		if (!this->callback(this->param, group, level, ike_sa, message))
		{
			this->listener->status = NEED_MORE;
			listener_done(this->listener);
		}
	}
}

METHOD(logger_t, listener_get_level, level_t,
	interface_logger_t *this, debug_t group)
{
	/* in order to allow callback listeners to decide what they want to log
	 * we request any log message, but only if we actually want logging */
	return this->callback == controller_cb_empty ? LEVEL_SILENT : LEVEL_PRIVATE;
}

METHOD(job_t, get_priority_medium, job_priority_t,
	job_t *this)
{
	return JOB_PRIO_MEDIUM;
}

METHOD(listener_t, ike_state_change, bool,
	interface_listener_t *this, ike_sa_t *ike_sa, ike_sa_state_t state)
{
	ike_sa_t *target;

	this->lock->lock(this->lock);
	target = this->ike_sa;
	this->lock->unlock(this->lock);

	if (target == ike_sa)
	{
		switch (state)
		{
			case IKE_ESTABLISHED:
			{
#ifdef ME
				peer_cfg_t *peer_cfg = ike_sa->get_peer_cfg(ike_sa);
#endif /* ME */
				/* we're done if we didn't initiate a CHILD_SA */
				if (!this->child_cfg
#ifdef ME
					/* the same is always true for mediation connections */
					|| peer_cfg->is_mediation(peer_cfg)
#endif /* ME */
					)
				{
					this->status = SUCCESS;
					return listener_done(this);
				}
				break;
			}
			case IKE_DESTROYING:
				return listener_done(this);
			default:
				break;
		}
	}
	return TRUE;
}

METHOD(listener_t, ike_state_change_terminate, bool,
	interface_listener_t *this, ike_sa_t *ike_sa, ike_sa_state_t state)
{
	ike_sa_t *target;

	this->lock->lock(this->lock);
	target = this->ike_sa;
	this->lock->unlock(this->lock);

	if (target == ike_sa)
	{
		switch (state)
		{
			case IKE_DESTROYING:
				this->status = SUCCESS;
				return listener_done(this);
			default:
				break;
		}
	}
	return TRUE;
}

METHOD(listener_t, child_state_change, bool,
	interface_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
	child_sa_state_t state)
{
	ike_sa_t *target;

	this->lock->lock(this->lock);
	target = this->ike_sa;
	this->lock->unlock(this->lock);

	if (target == ike_sa)
	{
		switch (state)
		{
			case CHILD_INSTALLED:
				this->status = SUCCESS;
				return listener_done(this);
			case CHILD_DESTROYING:
				switch (child_sa->get_state(child_sa))
				{
					case CHILD_RETRYING:
						/* retrying with a different DH group; survive another
						 * initiation round */
						this->status = NEED_MORE;
						return TRUE;
					case CHILD_CREATED:
						if (this->status == NEED_MORE)
						{
							this->status = FAILED;
							return TRUE;
						}
						break;
					default:
						break;
				}
				return listener_done(this);
			default:
				break;
		}
	}
	return TRUE;
}

METHOD(listener_t, child_state_change_terminate, bool,
	interface_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
	child_sa_state_t state)
{
	ike_sa_t *target;

	this->lock->lock(this->lock);
	target = this->ike_sa;
	this->lock->unlock(this->lock);

	if (target == ike_sa)
	{
		switch (state)
		{
			case CHILD_DESTROYING:
				switch (child_sa->get_state(child_sa))
				{
					case CHILD_DELETED:
						/* proper delete */
						this->status = SUCCESS;
						break;
					default:
						break;
				}
				return listener_done(this);
			default:
				break;
		}
	}
	return TRUE;
}

METHOD(job_t, destroy_job, void,
	interface_job_t *this)
{
	if (ref_put(&this->refcount))
	{
		this->listener.lock->destroy(this->listener.lock);
		DESTROY_IF(this->listener.done);
		free(this);
	}
}

METHOD(controller_t, create_ike_sa_enumerator, enumerator_t*,
	private_controller_t *this, bool wait)
{
	return charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager,
													 wait);
}

METHOD(job_t, initiate_execute, job_requeue_t,
	interface_job_t *job)
{
	ike_sa_t *ike_sa;
	interface_listener_t *listener = &job->listener;
	peer_cfg_t *peer_cfg = listener->peer_cfg;

	ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
														peer_cfg);
	peer_cfg->destroy(peer_cfg);
	if (!ike_sa)
	{
		DESTROY_IF(listener->child_cfg);
		listener->status = FAILED;
		listener_done(listener);
		return JOB_REQUEUE_NONE;
	}
	listener->lock->lock(listener->lock);
	listener->ike_sa = ike_sa;
	listener->lock->unlock(listener->lock);


	if (listener->options.limits && ike_sa->get_state(ike_sa) == IKE_CREATED)
	{	/* only check if we are not reusing an IKE_SA */
		u_int half_open, limit_half_open, limit_job_load;

		half_open = charon->ike_sa_manager->get_half_open_count(
										charon->ike_sa_manager, NULL, FALSE);
		limit_half_open = lib->settings->get_int(lib->settings,
										"%s.init_limit_half_open", 0, lib->ns);
		limit_job_load = lib->settings->get_int(lib->settings,
										"%s.init_limit_job_load", 0, lib->ns);
		if (limit_half_open && half_open >= limit_half_open)
		{
			DBG1(DBG_IKE, "abort IKE_SA initiation, half open IKE_SA count of "
				 "%d exceeds limit of %d", half_open, limit_half_open);
			charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
														ike_sa);
			DESTROY_IF(listener->child_cfg);
			listener->status = INVALID_STATE;
			listener_done(listener);
			return JOB_REQUEUE_NONE;
		}
		if (limit_job_load)
		{
			u_int jobs = 0, i;

			for (i = 0; i < JOB_PRIO_MAX; i++)
			{
				jobs += lib->processor->get_job_load(lib->processor, i);
			}
			if (jobs > limit_job_load)
			{
				DBG1(DBG_IKE, "abort IKE_SA initiation, job load of %d exceeds "
					 "limit of %d", jobs, limit_job_load);
				charon->ike_sa_manager->checkin_and_destroy(
												charon->ike_sa_manager, ike_sa);
				DESTROY_IF(listener->child_cfg);
				listener->status = INVALID_STATE;
				listener_done(listener);
				return JOB_REQUEUE_NONE;
			}
		}
	}

	if (ike_sa->initiate(ike_sa, listener->child_cfg, 0, NULL, NULL) == SUCCESS)
	{
		if (!listener->logger.callback)
		{
			listener->status = SUCCESS;
		}
		charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
	}
	else
	{
		listener->status = FAILED;
		charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
													ike_sa);
	}
	return JOB_REQUEUE_NONE;
}

METHOD(controller_t, initiate, status_t,
	private_controller_t *this, peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
	controller_cb_t callback, void *param, u_int timeout, bool limits)
{
	interface_job_t *job;
	status_t status;

	INIT(job,
		.listener = {
			.public = {
				.ike_state_change = _ike_state_change,
				.child_state_change = _child_state_change,
			},
			.logger = {
				.public = {
					.log = _listener_log,
					.get_level = _listener_get_level,
				},
				.callback = callback,
				.param = param,
			},
			.status = FAILED,
			.child_cfg = child_cfg,
			.peer_cfg = peer_cfg,
			.lock = spinlock_create(),
			.options.limits = limits,
		},
		.public = {
			.execute = _initiate_execute,
			.get_priority = _get_priority_medium,
			.destroy = _destroy_job,
		},
		.refcount = 1,
	);
	job->listener.logger.listener = &job->listener;
	thread_cleanup_push((void*)destroy_job, job);

	if (callback == NULL)
	{
		initiate_execute(job);
	}
	else
	{
		if (wait_for_listener(job, timeout))
		{
			job->listener.status = OUT_OF_RES;
		}
	}
	status = job->listener.status;
	thread_cleanup_pop(TRUE);
	return status;
}

METHOD(job_t, terminate_ike_execute, job_requeue_t,
	interface_job_t *job)
{
	interface_listener_t *listener = &job->listener;
	uint32_t unique_id = listener->id;
	ike_sa_t *ike_sa;

	ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
													unique_id);
	if (!ike_sa)
	{
		DBG1(DBG_IKE, "unable to terminate IKE_SA: ID %d not found", unique_id);
		listener->status = NOT_FOUND;
		/* release listener */
		listener_done(listener);
		return JOB_REQUEUE_NONE;
	}
	listener->lock->lock(listener->lock);
	listener->ike_sa = ike_sa;
	listener->lock->unlock(listener->lock);

	if (!listener->logger.callback)
	{	/* if we don't wait for the result, either outcome below is a success */
		listener->status = SUCCESS;
	}

	if (ike_sa->delete(ike_sa, listener->options.force) != DESTROY_ME)
	{	/* delete queued */
		charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
	}
	else
	{
		charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
													ike_sa);
	}
	return JOB_REQUEUE_NONE;
}

METHOD(controller_t, terminate_ike, status_t,
	controller_t *this, uint32_t unique_id, bool force,
	controller_cb_t callback, void *param, u_int timeout)
{
	interface_job_t *job;
	status_t status;

	INIT(job,
		.listener = {
			.public = {
				.ike_state_change = _ike_state_change_terminate,
			},
			.logger = {
				.public = {
					.log = _listener_log,
					.get_level = _listener_get_level,
				},
				.callback = callback,
				.param = param,
			},
			.status = FAILED,
			.id = unique_id,
			.lock = spinlock_create(),
		},
		.public = {
			.execute = _terminate_ike_execute,
			.get_priority = _get_priority_medium,
			.destroy = _destroy_job,
		},
		.refcount = 1,
	);
	job->listener.logger.listener = &job->listener;
	thread_cleanup_push((void*)destroy_job, job);

	if (callback == NULL)
	{
		job->listener.options.force = force;
		terminate_ike_execute(job);
	}
	else
	{
		if (!timeout)
		{
			job->listener.options.force = force;
		}
		if (wait_for_listener(job, timeout))
		{
			job->listener.status = OUT_OF_RES;

			if (force)
			{	/* force termination once timeout is reached */
				job->listener.options.force = TRUE;
				terminate_ike_execute(job);
			}
		}
	}
	status = job->listener.status;
	thread_cleanup_pop(TRUE);
	return status;
}

METHOD(job_t, terminate_child_execute, job_requeue_t,
	interface_job_t *job)
{
	interface_listener_t *listener = &job->listener;
	uint32_t id = listener->id;
	child_sa_t *child_sa;
	ike_sa_t *ike_sa;

	ike_sa = charon->child_sa_manager->checkout_by_id(charon->child_sa_manager,
													  id, &child_sa);
	if (!ike_sa)
	{
		DBG1(DBG_IKE, "unable to terminate, CHILD_SA with ID %d not found", id);
		listener->status = NOT_FOUND;
		/* release listener */
		listener_done(listener);
		return JOB_REQUEUE_NONE;
	}
	listener->lock->lock(listener->lock);
	listener->ike_sa = ike_sa;
	listener->lock->unlock(listener->lock);

	if (ike_sa->delete_child_sa(ike_sa, child_sa->get_protocol(child_sa),
					child_sa->get_spi(child_sa, TRUE), FALSE) != DESTROY_ME)
	{
		if (!listener->logger.callback)
		{
			listener->status = SUCCESS;
		}
		charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
	}
	else
	{
		listener->status = FAILED;
		charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
													ike_sa);
	}
	return JOB_REQUEUE_NONE;
}

METHOD(controller_t, terminate_child, status_t,
	controller_t *this, uint32_t unique_id,
	controller_cb_t callback, void *param, u_int timeout)
{
	interface_job_t *job;
	status_t status;

	INIT(job,
		.listener = {
			.public = {
				.ike_state_change = _ike_state_change_terminate,
				.child_state_change = _child_state_change_terminate,
			},
			.logger = {
				.public = {
					.log = _listener_log,
					.get_level = _listener_get_level,
				},
				.callback = callback,
				.param = param,
			},
			.status = FAILED,
			.id = unique_id,
			.lock = spinlock_create(),
		},
		.public = {
			.execute = _terminate_child_execute,
			.get_priority = _get_priority_medium,
			.destroy = _destroy_job,
		},
		.refcount = 1,
	);
	job->listener.logger.listener = &job->listener;
	thread_cleanup_push((void*)destroy_job, job);

	if (callback == NULL)
	{
		terminate_child_execute(job);
	}
	else
	{
		if (wait_for_listener(job, timeout))
		{
			job->listener.status = OUT_OF_RES;
		}
	}
	status = job->listener.status;
	thread_cleanup_pop(TRUE);
	return status;
}

/**
 * See header
 */
bool controller_cb_empty(void *param, debug_t group, level_t level,
						 ike_sa_t *ike_sa, const char *message)
{
	return TRUE;
}

METHOD(controller_t, destroy, void,
	private_controller_t *this)
{
	free(this);
}

/*
 * Described in header-file
 */
controller_t *controller_create(void)
{
	private_controller_t *this;

	INIT(this,
		.public = {
			.create_ike_sa_enumerator = _create_ike_sa_enumerator,
			.initiate = _initiate,
			.terminate_ike = _terminate_ike,
			.terminate_child = _terminate_child,
			.destroy = _destroy,
		},
	);

	return &this->public;
}
