/* Copyright (c) 2012 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.
 */

#define _GNU_SOURCE /* Needed for Linux socket credential passing. */

#ifdef CRAS_DBUS
#include <dbus/dbus.h>
#endif
#include <errno.h>
#include <poll.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>
#include <syslog.h>
#include <unistd.h>

#ifdef CRAS_DBUS
#include "cras_a2dp_endpoint.h"
#include "cras_bt_manager.h"
#include "cras_bt_device.h"
#include "cras_bt_player.h"
#include "cras_dbus.h"
#include "cras_dbus_control.h"
#include "cras_hfp_ag_profile.h"
#include "cras_telephony.h"
#endif
#include "cras_alert.h"
#include "cras_audio_thread_monitor.h"
#include "cras_config.h"
#include "cras_device_monitor.h"
#include "cras_hotword_handler.h"
#include "cras_iodev_list.h"
#include "cras_main_message.h"
#include "cras_messages.h"
#include "cras_metrics.h"
#include "cras_non_empty_audio_handler.h"
#include "cras_observer.h"
#include "cras_rclient.h"
#include "cras_server.h"
#include "cras_server_metrics.h"
#include "cras_system_state.h"
#include "cras_tm.h"
#include "cras_types.h"
#include "cras_udev.h"
#include "cras_util.h"
#include "cras_mix.h"
#include "utlist.h"

/* Store a list of clients that are attached to the server.
 * Members:
 *    id - Unique identifier for this client.
 *    fd - socket file descriptor used to communicate with client.
 *    ucred - Process, user, and group ID of the client.
 *    client - rclient to handle messages from this client.
 *    pollfd - Pointer to struct pollfd for this callback.
 */
struct attached_client {
	size_t id;
	int fd;
	struct ucred ucred;
	struct cras_rclient *client;
	struct pollfd *pollfd;
	struct attached_client *next, *prev;
};

/* Stores file descriptors to callback mappings for clients. Callback/fd/data
 * args are registered by clients.  When fd is ready, the callback will be
 * called on the main server thread and the callback data will be passed back to
 * it.  This allows the use of the main server loop instead of spawning a thread
 * to watch file descriptors.  The client can then read or write the fd.
 * Members:
 *    fd - The file descriptor passed to select.
 *    callback - The funciton to call when fd is ready.
 *    callback_data - Pointer passed to the callback.
 *    pollfd - Pointer to struct pollfd for this callback.
 *    events - The events to poll for.
 */
struct client_callback {
	int select_fd;
	void (*callback)(void *data, int revents);
	void *callback_data;
	struct pollfd *pollfd;
	int deleted;
	int events;
	struct client_callback *prev, *next;
};

/* Stores callback function and argument data to be executed later. */
struct system_task {
	void (*callback)(void *);
	void *callback_data;
	struct system_task *next, *prev;
};

/* A structure wraps data related to server socket. */
struct server_socket {
	struct sockaddr_un addr;
	int fd;
	enum CRAS_CONNECTION_TYPE type;
};

/* Local server data. */
struct server_data {
	struct attached_client *clients_head;
	size_t num_clients;
	struct client_callback *client_callbacks;
	struct system_task *system_tasks;
	size_t num_client_callbacks;
	size_t next_client_id;
	struct server_socket server_sockets[CRAS_NUM_CONN_TYPE];
} server_instance;

/* Cleanup a given server_socket */
static void server_socket_cleanup(struct server_socket *socket)
{
	if (socket && socket->fd >= 0) {
		close(socket->fd);
		socket->fd = -1;
		unlink(socket->addr.sun_path);
	}
}

/* Remove a client from the list and destroy it.  Calling rclient_destroy will
 * also free all the streams owned by the client */
static void remove_client(struct attached_client *client)
{
	close(client->fd);
	DL_DELETE(server_instance.clients_head, client);
	server_instance.num_clients--;
	cras_rclient_destroy(client->client);
	free(client);
}

/* This is called when "select" indicates that the client has written data to
 * the socket.  Read out one message and pass it to the client message handler.
 */
static void handle_message_from_client(struct attached_client *client)
{
	uint8_t buf[CRAS_SERV_MAX_MSG_SIZE];
	int nread;
	unsigned int num_fds = 2;
	int fds[num_fds];

	nread = cras_recv_with_fds(client->fd, buf, sizeof(buf), fds, &num_fds);
	if (nread < 0)
		goto read_error;
	if (cras_rclient_buffer_from_client(client->client, buf, nread, fds,
					    num_fds) < 0)
		goto read_error;
	return;

read_error:
	for (int i = 0; i < num_fds; i++)
		if (fds[i] >= 0)
			close(fds[i]);
	switch (nread) {
	case 0:
		break;
	default:
		syslog(LOG_DEBUG, "read err [%d] '%s', removing client %zu",
		       -nread, strerror(-nread), client->id);
		break;
	}
	remove_client(client);
}

/* Discovers and fills in info about the client that can be obtained from the
 * socket. The pid of the attaching client identifies it in logs. */
static void fill_client_info(struct attached_client *client)
{
	socklen_t ucred_length = sizeof(client->ucred);

	if (getsockopt(client->fd, SOL_SOCKET, SO_PEERCRED, &client->ucred,
		       &ucred_length))
		syslog(LOG_INFO, "Failed to get client socket info\n");
}

/* Fills the server_state with the current list of attached clients. */
static void send_client_list_to_clients(struct server_data *serv)
{
	struct attached_client *c;
	struct cras_attached_client_info *info;
	struct cras_server_state *state;
	unsigned i;

	state = cras_system_state_update_begin();
	if (!state)
		return;

	state->num_attached_clients =
		MIN(CRAS_MAX_ATTACHED_CLIENTS, serv->num_clients);

	info = state->client_info;
	i = 0;
	DL_FOREACH (serv->clients_head, c) {
		info->id = c->id;
		info->pid = c->ucred.pid;
		info->uid = c->ucred.uid;
		info->gid = c->ucred.gid;
		info++;
		if (++i == CRAS_MAX_ATTACHED_CLIENTS)
			break;
	}

	cras_system_state_update_complete();
}

/* Handles requests from a client to attach to the server.  Create a local
 * structure to track the client, assign it a unique id and let it attach */
static void handle_new_connection(struct server_socket *server_socket)
{
	int connection_fd;
	struct attached_client *poll_client;
	socklen_t address_length;

	poll_client = malloc(sizeof(struct attached_client));
	if (poll_client == NULL) {
		syslog(LOG_ERR, "Allocating poll_client");
		return;
	}

	memset(&address_length, 0, sizeof(address_length));
	connection_fd = accept(server_socket->fd,
			       (struct sockaddr *)&server_socket->addr,
			       &address_length);
	if (connection_fd < 0) {
		syslog(LOG_ERR, "connecting");
		free(poll_client);
		return;
	}

	/* find next available client id */
	while (1) {
		struct attached_client *out;
		DL_SEARCH_SCALAR(server_instance.clients_head, out, id,
				 server_instance.next_client_id);
		poll_client->id = server_instance.next_client_id;
		server_instance.next_client_id++;
		if (out == NULL)
			break;
	}

	/* When full, getting an error is preferable to blocking. */
	cras_make_fd_nonblocking(connection_fd);

	poll_client->fd = connection_fd;
	poll_client->next = NULL;
	poll_client->pollfd = NULL;
	fill_client_info(poll_client);

	poll_client->client = cras_rclient_create(
		connection_fd, poll_client->id, server_socket->type);
	if (poll_client->client == NULL) {
		syslog(LOG_ERR, "failed to create client");
		goto error;
	}

	DL_APPEND(server_instance.clients_head, poll_client);
	server_instance.num_clients++;
	/* Send a current list of available inputs and outputs. */
	cras_iodev_list_update_device_list();
	send_client_list_to_clients(&server_instance);
	return;
error:
	close(connection_fd);
	free(poll_client);
	return;
}

/* Add a file descriptor to be passed to select in the main loop. This is
 * registered with system state so that it is called when any client asks to
 * have a callback triggered based on an fd being readable. */
static int add_select_fd(int fd, void (*cb)(void *data, int events),
			 void *callback_data, int events, void *server_data)
{
	struct client_callback *new_cb;
	struct client_callback *client_cb;
	struct server_data *serv;

	serv = (struct server_data *)server_data;
	if (serv == NULL)
		return -EINVAL;

	/* Check if fd already exists. */
	DL_FOREACH (serv->client_callbacks, client_cb)
		if (client_cb->select_fd == fd && !client_cb->deleted)
			return -EEXIST;

	new_cb = (struct client_callback *)calloc(1, sizeof(*new_cb));
	if (new_cb == NULL)
		return -ENOMEM;

	new_cb->select_fd = fd;
	new_cb->callback = cb;
	new_cb->callback_data = callback_data;
	new_cb->deleted = 0;
	new_cb->events = events;
	new_cb->pollfd = NULL;

	DL_APPEND(serv->client_callbacks, new_cb);
	server_instance.num_client_callbacks++;
	return 0;
}

/* Removes a file descriptor to be passed to select in the main loop. This is
 * registered with system state so that it is called when any client asks to
 * remove a callback added with add_select_fd. */
static void rm_select_fd(int fd, void *server_data)
{
	struct server_data *serv;
	struct client_callback *client_cb;

	serv = (struct server_data *)server_data;
	if (serv == NULL)
		return;

	DL_FOREACH (serv->client_callbacks, client_cb)
		if (client_cb->select_fd == fd)
			client_cb->deleted = 1;
}

/* Creates a new task entry and append to system_tasks list, which will be
 * executed in main loop later without wait time.
 */
static int add_task(void (*cb)(void *data), void *callback_data,
		    void *server_data)
{
	struct server_data *serv;
	struct system_task *new_task;

	serv = (struct server_data *)server_data;
	if (serv == NULL)
		return -EINVAL;

	new_task = (struct system_task *)calloc(1, sizeof(*new_task));
	if (new_task == NULL)
		return -ENOMEM;

	new_task->callback = cb;
	new_task->callback_data = callback_data;

	DL_APPEND(serv->system_tasks, new_task);
	return 0;
}

/* Cleans up the file descriptor list removing items deleted during the main
 * loop iteration. */
static void cleanup_select_fds(void *server_data)
{
	struct server_data *serv;
	struct client_callback *client_cb;

	serv = (struct server_data *)server_data;
	if (serv == NULL)
		return;

	DL_FOREACH (serv->client_callbacks, client_cb)
		if (client_cb->deleted) {
			DL_DELETE(serv->client_callbacks, client_cb);
			server_instance.num_client_callbacks--;
			free(client_cb);
		}
}

/* Checks that at least two outputs are present (one will be the "empty"
 * default device. */
void check_output_exists(struct cras_timer *t, void *data)
{
	if (cras_iodev_list_get_outputs(NULL) < 2)
		cras_metrics_log_event(kNoCodecsFoundMetric);
}

#if defined(__amd64__)
/* CPU detection - probaby best to move this elsewhere */
static void cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
		  unsigned int *edx, unsigned int op)
{
	// clang-format off
	__asm__ __volatile__ (
		"cpuid"
		: "=a" (*eax),
		  "=b" (*ebx),
		  "=c" (*ecx),
		  "=d" (*edx)
		: "a" (op), "c" (0)
	);
	// clang-format on
}

static unsigned int cpu_x86_flags(void)
{
	unsigned int eax, ebx, ecx, edx, id;
	unsigned int cpu_flags = 0;

	cpuid(&id, &ebx, &ecx, &edx, 0);

	if (id >= 1) {
		cpuid(&eax, &ebx, &ecx, &edx, 1);

		if (ecx & (1 << 20))
			cpu_flags |= CPU_X86_SSE4_2;

		if (ecx & (1 << 28))
			cpu_flags |= CPU_X86_AVX;

		if (ecx & (1 << 12))
			cpu_flags |= CPU_X86_FMA;
	}

	if (id >= 7) {
		cpuid(&eax, &ebx, &ecx, &edx, 7);

		if (ebx & (1 << 5))
			cpu_flags |= CPU_X86_AVX2;
	}

	return cpu_flags;
}
#endif

int cpu_get_flags(void)
{
#if defined(__amd64__)
	return cpu_x86_flags();
#endif
	return 0;
}

/*
 * Exported Interface.
 */

int cras_server_init()
{
	/* Log to syslog. */
	openlog("cras_server", LOG_PID, LOG_USER);

	server_instance.next_client_id = RESERVED_CLIENT_IDS;

	/* Initialize global observer. */
	cras_observer_server_init();

	/* init mixer with CPU capabilities */
	cras_mix_init(cpu_get_flags());

	/* Allow clients to register callbacks for file descriptors.
	 * add_select_fd and rm_select_fd will add and remove file descriptors
	 * from the list that are passed to select in the main loop below. */
	cras_system_set_select_handler(add_select_fd, rm_select_fd,
				       &server_instance);
	cras_system_set_add_task_handler(add_task, &server_instance);
	cras_main_message_init();

	/* Initializes all server_sockets */
	for (int conn_type = 0; conn_type < CRAS_NUM_CONN_TYPE; conn_type++) {
		server_instance.server_sockets[conn_type].fd = -1;
	}

	return 0;
}

/*
 * Creates a server socket with given connection type and listens on it.
 * The socket_file will be created under cras_config_get_system_socket_file_dir
 * with permission=0770. The socket_fd will be listened with parameter
 * backlog=5.
 *
 * Returns 0 on success and leaves the created fd and the address information
 * in server_socket.
 * When error occurs, the created fd will be closed and the file path will be
 * unlinked and returns negative error code.
 */
static int create_and_listen_server_socket(enum CRAS_CONNECTION_TYPE conn_type,
					   struct server_socket *server_socket)
{
	int socket_fd = -1;
	int rc = 0;
	struct sockaddr_un *addr = &server_socket->addr;

	socket_fd = socket(PF_UNIX, SOCK_SEQPACKET, 0);
	if (socket_fd < 0) {
		syslog(LOG_ERR, "Main server socket failed.");
		rc = socket_fd;
		goto error;
	}

	memset(addr, 0, sizeof(*addr));
	addr->sun_family = AF_UNIX;
	rc = cras_fill_socket_path(conn_type, addr->sun_path);
	if (rc < 0)
		goto error;
	unlink(addr->sun_path);

	/* Linux quirk: calling fchmod before bind, sets the permissions of the
	 * file created by bind, leaving no window for it to be modified. Start
	 * with very restricted permissions. */
	rc = fchmod(socket_fd, 0700);
	if (rc < 0)
		goto error;

	rc = bind(socket_fd, (struct sockaddr *)addr,
		  sizeof(struct sockaddr_un));
	if (rc < 0) {
		syslog(LOG_ERR, "Bind to server socket failed.");
		rc = -errno;
		goto error;
	}

	/* Let other members in our group play audio through this socket. */
	rc = chmod(addr->sun_path, 0770);
	if (rc < 0)
		goto error;

	if (listen(socket_fd, 5) != 0) {
		syslog(LOG_ERR, "Listen on server socket failed.");
		rc = -errno;
		goto error;
	}

	server_socket->fd = socket_fd;
	server_socket->type = conn_type;
	return 0;
error:
	if (socket_fd >= 0) {
		close(socket_fd);
		unlink(addr->sun_path);
	}
	return rc;
}

/* Cleans up all server_socket in server_instance */
static void cleanup_server_sockets()
{
	for (int conn_type = 0; conn_type < CRAS_NUM_CONN_TYPE; conn_type++) {
		server_socket_cleanup(
			&server_instance.server_sockets[conn_type]);
	}
}

int cras_server_run(unsigned int profile_disable_mask)
{
	static const unsigned int OUTPUT_CHECK_MS = 5 * 1000;
#ifdef CRAS_DBUS
	DBusConnection *dbus_conn;
#endif
	int rc = 0;
	struct attached_client *elm;
	struct client_callback *client_cb;
	struct system_task *tasks;
	struct system_task *system_task;
	struct cras_tm *tm;
	struct timespec ts, *poll_timeout;
	int timers_active;
	struct pollfd *pollfds;
	unsigned int pollfds_size = 32;
	unsigned int num_pollfds, poll_size_needed;

	pollfds = malloc(sizeof(*pollfds) * pollfds_size);

	cras_udev_start_sound_subsystem_monitor();
#ifdef CRAS_DBUS
	cras_bt_device_start_monitor();
#endif

	cras_server_metrics_init();

	cras_device_monitor_init();

	cras_hotword_handler_init();

	cras_non_empty_audio_handler_init();

	cras_audio_thread_monitor_init();

#ifdef CRAS_DBUS
	dbus_threads_init_default();
	dbus_conn = cras_dbus_connect_system_bus();
	if (dbus_conn) {
		cras_bt_start(dbus_conn);
		if (!(profile_disable_mask & CRAS_SERVER_PROFILE_MASK_HFP))
			cras_hfp_ag_profile_create(dbus_conn);
		if (!(profile_disable_mask & CRAS_SERVER_PROFILE_MASK_HSP))
			cras_hsp_ag_profile_create(dbus_conn);
		cras_telephony_start(dbus_conn);
		if (!(profile_disable_mask & CRAS_SERVER_PROFILE_MASK_A2DP))
			cras_a2dp_endpoint_create(dbus_conn);
		cras_bt_player_create(dbus_conn);
		cras_dbus_control_start(dbus_conn);
	}
#endif

	for (int conn_type = 0; conn_type < CRAS_NUM_CONN_TYPE; conn_type++) {
		rc = create_and_listen_server_socket(
			conn_type, &server_instance.server_sockets[conn_type]);
		if (rc < 0)
			goto bail;
	}

	tm = cras_system_state_get_tm();
	if (!tm) {
		syslog(LOG_ERR, "Getting timer manager.");
		rc = -ENOMEM;
		goto bail;
	}

	/* After a delay, make sure there is at least one real output device. */
	cras_tm_create_timer(tm, OUTPUT_CHECK_MS, check_output_exists, 0);

	/* Main server loop - client callbacks are run from this context. */
	while (1) {
		poll_size_needed = CRAS_NUM_CONN_TYPE +
				   server_instance.num_clients +
				   server_instance.num_client_callbacks;
		if (poll_size_needed > pollfds_size) {
			pollfds_size = 2 * poll_size_needed;
			pollfds = realloc(pollfds,
					  sizeof(*pollfds) * pollfds_size);
		}

		for (int conn_type = 0; conn_type < CRAS_NUM_CONN_TYPE;
		     conn_type++) {
			pollfds[conn_type].fd =
				server_instance.server_sockets[conn_type].fd;
			pollfds[conn_type].events = POLLIN;
		}
		num_pollfds = CRAS_NUM_CONN_TYPE;

		DL_FOREACH (server_instance.clients_head, elm) {
			pollfds[num_pollfds].fd = elm->fd;
			pollfds[num_pollfds].events = POLLIN;
			elm->pollfd = &pollfds[num_pollfds];
			num_pollfds++;
		}
		DL_FOREACH (server_instance.client_callbacks, client_cb) {
			if (client_cb->deleted)
				continue;
			pollfds[num_pollfds].fd = client_cb->select_fd;
			pollfds[num_pollfds].events = client_cb->events;
			client_cb->pollfd = &pollfds[num_pollfds];
			num_pollfds++;
		}

		tasks = server_instance.system_tasks;
		server_instance.system_tasks = NULL;
		DL_FOREACH (tasks, system_task) {
			system_task->callback(system_task->callback_data);
			DL_DELETE(tasks, system_task);
			free(system_task);
		}

		timers_active = cras_tm_get_next_timeout(tm, &ts);

		/*
		 * If new client task has been scheduled, no need to wait
		 * for timeout, just do another loop to execute them.
		 */
		if (server_instance.system_tasks)
			poll_timeout = NULL;
		else
			poll_timeout = timers_active ? &ts : NULL;

		rc = ppoll(pollfds, num_pollfds, poll_timeout, NULL);
		if (rc < 0)
			continue;

		cras_tm_call_callbacks(tm);

		/* Check for new connections. */
		for (int conn_type = 0; conn_type < CRAS_NUM_CONN_TYPE;
		     conn_type++) {
			if (pollfds[conn_type].revents & POLLIN)
				handle_new_connection(
					&server_instance
						 .server_sockets[conn_type]);
		}

		/* Check if there are messages pending for any clients. */
		DL_FOREACH (server_instance.clients_head, elm)
			if (elm->pollfd && elm->pollfd->revents & POLLIN)
				handle_message_from_client(elm);
		/* Check any client-registered fd/callback pairs. */
		DL_FOREACH (server_instance.client_callbacks, client_cb)
			if (!client_cb->deleted && client_cb->pollfd &&
			    (client_cb->pollfd->revents & client_cb->events))
				client_cb->callback(client_cb->callback_data,
						    client_cb->pollfd->revents);

		cleanup_select_fds(&server_instance);

#ifdef CRAS_DBUS
		if (dbus_conn)
			cras_dbus_dispatch(dbus_conn);
#endif

		cras_alert_process_all_pending_alerts();
	}

bail:
	cleanup_server_sockets();
	free(pollfds);
	cras_observer_server_free();
	return rc;
}

void cras_server_send_to_all_clients(const struct cras_client_message *msg)
{
	struct attached_client *client;

	DL_FOREACH (server_instance.clients_head, client)
		cras_rclient_send_message(client->client, msg, NULL, 0);
}
