/* Copyright 2015 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 <stdio.h>
#include <stdlib.h>
#include <syslog.h>

#include "cras_main_message.h"
#include "cras_system_state.h"
#include "cras_util.h"

/* Callback to handle specific type of main thread message. */
struct cras_main_msg_callback {
	enum CRAS_MAIN_MESSAGE_TYPE type;
	cras_message_callback callback;
	void *callback_data;
	struct cras_main_msg_callback *prev, *next;
};

static int main_msg_fds[2];
static struct cras_main_msg_callback *main_msg_callbacks;

int cras_main_message_add_handler(enum CRAS_MAIN_MESSAGE_TYPE type,
				  cras_message_callback callback,
				  void *callback_data)
{
	struct cras_main_msg_callback *msg_cb;

	DL_FOREACH (main_msg_callbacks, msg_cb) {
		if (msg_cb->type == type) {
			syslog(LOG_ERR, "Main message type %u already exists",
			       type);
			return -EEXIST;
		}
	}

	msg_cb = (struct cras_main_msg_callback *)calloc(1, sizeof(*msg_cb));
	msg_cb->type = type;
	msg_cb->callback = callback;
	msg_cb->callback_data = callback_data;

	DL_APPEND(main_msg_callbacks, msg_cb);
	return 0;
}

int cras_main_message_send(struct cras_main_message *msg)
{
	int err;

	err = write(main_msg_fds[1], msg, msg->length);
	if (err < 0) {
		syslog(LOG_ERR, "Failed to send main message, type %u",
		       msg->type);
		return err;
	}
	return 0;
}

static int read_main_message(int msg_fd, uint8_t *buf, size_t max_len)
{
	int to_read, nread, rc;
	struct cras_main_message *msg = (struct cras_main_message *)buf;

	nread = read(msg_fd, buf, sizeof(msg->length));
	if (nread < 0)
		return nread;
	if (msg->length > max_len)
		return -ENOMEM;

	to_read = msg->length - nread;
	rc = read(msg_fd, &buf[0] + nread, to_read);
	if (rc < 0)
		return rc;
	return 0;
}

static void handle_main_messages(void *arg, int revents)
{
	uint8_t buf[256];
	int rc;
	struct cras_main_msg_callback *main_msg_cb;
	struct cras_main_message *msg = (struct cras_main_message *)buf;

	rc = read_main_message(main_msg_fds[0], buf, sizeof(buf));
	if (rc < 0) {
		syslog(LOG_ERR, "Failed to read main message");
		return;
	}

	DL_FOREACH (main_msg_callbacks, main_msg_cb) {
		if (main_msg_cb->type == msg->type) {
			main_msg_cb->callback(msg, main_msg_cb->callback_data);
			break;
		}
	}
}

void cras_main_message_init()
{
	int rc;

	rc = pipe(main_msg_fds);
	if (rc < 0) {
		syslog(LOG_ERR, "Fatal: main message init");
		exit(-ENOMEM);
	}

	/* When full it's preferred to get error instead of blocked. */
	cras_make_fd_nonblocking(main_msg_fds[0]);
	cras_make_fd_nonblocking(main_msg_fds[1]);

	cras_system_add_select_fd(main_msg_fds[0], handle_main_messages, NULL,
				  POLLIN);
}
