/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <errno.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>

#include "cras_alert.h"
#include "utlist.h"

/* A list of callbacks for an alert */
struct cras_alert_cb_list {
	cras_alert_cb callback;
	void *arg;
	struct cras_alert_cb_list *prev, *next;
};

/* A list of data args to callbacks. Variable-length structure. */
struct cras_alert_data {
	struct cras_alert_data *prev, *next;
	/* This field must be the last in this structure. */
	char buf[];
};

struct cras_alert {
	int pending;
	unsigned int flags;
	cras_alert_prepare prepare;
	struct cras_alert_cb_list *callbacks;
	struct cras_alert_data *data;
	struct cras_alert *prev, *next;
};

/* A list of all alerts in the system */
static struct cras_alert *all_alerts;
/* If there is any alert pending. */
static int has_alert_pending;

struct cras_alert *cras_alert_create(cras_alert_prepare prepare,
				     unsigned int flags)
{
	struct cras_alert *alert;
	alert = calloc(1, sizeof(*alert));
	if (!alert)
		return NULL;
	alert->prepare = prepare;
	alert->flags = flags;
	DL_APPEND(all_alerts, alert);
	return alert;
}

int cras_alert_add_callback(struct cras_alert *alert, cras_alert_cb cb,
			    void *arg)
{
	struct cras_alert_cb_list *alert_cb;

	if (cb == NULL)
		return -EINVAL;

	DL_FOREACH (alert->callbacks, alert_cb)
		if (alert_cb->callback == cb && alert_cb->arg == arg)
			return -EEXIST;

	alert_cb = calloc(1, sizeof(*alert_cb));
	if (alert_cb == NULL)
		return -ENOMEM;
	alert_cb->callback = cb;
	alert_cb->arg = arg;
	DL_APPEND(alert->callbacks, alert_cb);
	return 0;
}

int cras_alert_rm_callback(struct cras_alert *alert, cras_alert_cb cb,
			   void *arg)
{
	struct cras_alert_cb_list *alert_cb;

	DL_FOREACH (alert->callbacks, alert_cb)
		if (alert_cb->callback == cb && alert_cb->arg == arg) {
			DL_DELETE(alert->callbacks, alert_cb);
			free(alert_cb);
			return 0;
		}
	return -ENOENT;
}

/* Checks if the alert is pending, and invoke the prepare function and callbacks
 * if so. */
static void cras_alert_process(struct cras_alert *alert)
{
	struct cras_alert_cb_list *cb;
	struct cras_alert_data *data;

	if (!alert->pending)
		return;

	alert->pending = 0;
	if (alert->prepare)
		alert->prepare(alert);

	if (!alert->data) {
		DL_FOREACH (alert->callbacks, cb)
			cb->callback(cb->arg, NULL);
	}

	/* Have data arguments, pass each to the callbacks. */
	DL_FOREACH (alert->data, data) {
		DL_FOREACH (alert->callbacks, cb)
			cb->callback(cb->arg, (void *)data->buf);
		DL_DELETE(alert->data, data);
		free(data);
	}
}

void cras_alert_pending(struct cras_alert *alert)
{
	alert->pending = 1;
	has_alert_pending = 1;
}

void cras_alert_pending_data(struct cras_alert *alert, void *data,
			     size_t data_size)
{
	struct cras_alert_data *d;

	alert->pending = 1;
	has_alert_pending = 1;
	d = calloc(1, offsetof(struct cras_alert_data, buf) + data_size);
	memcpy(d->buf, data, data_size);

	if (!(alert->flags & CRAS_ALERT_FLAG_KEEP_ALL_DATA) && alert->data) {
		/* There will never be more than one item in the list. */
		free(alert->data);
		alert->data = NULL;
	}

	/* Even when there is only one item, it is important to use DL_APPEND
	 * here so that d's next and prev pointers are setup correctly. */
	DL_APPEND(alert->data, d);
}

void cras_alert_process_all_pending_alerts()
{
	struct cras_alert *alert;

	while (has_alert_pending) {
		has_alert_pending = 0;
		DL_FOREACH (all_alerts, alert)
			cras_alert_process(alert);
	}
}

void cras_alert_destroy(struct cras_alert *alert)
{
	struct cras_alert_cb_list *cb;
	struct cras_alert_data *data;

	if (!alert)
		return;

	DL_FOREACH (alert->callbacks, cb) {
		DL_DELETE(alert->callbacks, cb);
		free(cb);
	}

	DL_FOREACH (alert->data, data) {
		DL_DELETE(alert->data, data);
		free(data);
	}

	alert->callbacks = NULL;
	DL_DELETE(all_alerts, alert);
	free(alert);
}

void cras_alert_destroy_all()
{
	struct cras_alert *alert;
	DL_FOREACH (all_alerts, alert)
		cras_alert_destroy(alert);
}
