/* Copyright (c) 2014 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 <sys/ioctl.h>
#include <pthread.h>
#include <sys/param.h>
#include <syslog.h>

#include "audio_thread.h"
#include "byte_buffer.h"
#include "cras_audio_area.h"
#include "cras_config.h"
#include "cras_iodev.h"
#include "cras_iodev_list.h"
#include "cras_types.h"
#include "cras_util.h"
#include "test_iodev.h"
#include "utlist.h"

#define TEST_BUFFER_SIZE (16 * 1024)

static size_t test_supported_rates[] = { 16000, 0 };

static size_t test_supported_channel_counts[] = { 1, 0 };

static snd_pcm_format_t test_supported_formats[] = { SND_PCM_FORMAT_S16_LE, 0 };

struct test_iodev {
	struct cras_iodev base;
	int fd;
	struct byte_buffer *audbuff;
	unsigned int fmt_bytes;
};

/*
 * iodev callbacks.
 */

static int frames_queued(const struct cras_iodev *iodev,
			 struct timespec *tstamp)
{
	struct test_iodev *testio = (struct test_iodev *)iodev;
	int available;

	if (testio->fd < 0)
		return 0;
	ioctl(testio->fd, FIONREAD, &available);
	clock_gettime(CLOCK_MONOTONIC_RAW, tstamp);
	return available / testio->fmt_bytes;
}

static int delay_frames(const struct cras_iodev *iodev)
{
	return 0;
}

static int close_dev(struct cras_iodev *iodev)
{
	struct test_iodev *testio = (struct test_iodev *)iodev;

	byte_buffer_destroy(&testio->audbuff);
	testio->audbuff = NULL;
	cras_iodev_free_audio_area(iodev);
	return 0;
}

static int configure_dev(struct cras_iodev *iodev)
{
	struct test_iodev *testio = (struct test_iodev *)iodev;

	if (iodev->format == NULL)
		return -EINVAL;

	cras_iodev_init_audio_area(iodev, iodev->format->num_channels);
	testio->fmt_bytes = cras_get_format_bytes(iodev->format);
	testio->audbuff =
		byte_buffer_create(TEST_BUFFER_SIZE * testio->fmt_bytes);

	return 0;
}

static int get_buffer(struct cras_iodev *iodev, struct cras_audio_area **area,
		      unsigned *frames)
{
	struct test_iodev *testio = (struct test_iodev *)iodev;
	unsigned int readable;
	uint8_t *buff;

	buff = buf_read_pointer_size(testio->audbuff, &readable);
	*frames = MIN(*frames, readable);

	iodev->area->frames = *frames;
	cras_audio_area_config_buf_pointers(iodev->area, iodev->format, buff);
	*area = iodev->area;
	return 0;
}

static int put_buffer(struct cras_iodev *iodev, unsigned frames)
{
	struct test_iodev *testio = (struct test_iodev *)iodev;

	/* Input */
	buf_increment_read(testio->audbuff,
			   (size_t)frames * (size_t)testio->fmt_bytes);

	return 0;
}

static int get_buffer_fd_read(struct cras_iodev *iodev,
			      struct cras_audio_area **area, unsigned *frames)
{
	struct test_iodev *testio = (struct test_iodev *)iodev;
	int nread;
	uint8_t *write_ptr;
	unsigned int avail;

	if (testio->fd < 0) {
		*frames = 0;
		return 0;
	}

	write_ptr = buf_write_pointer_size(testio->audbuff, &avail);
	avail = MIN(avail, *frames * testio->fmt_bytes);
	nread = read(testio->fd, write_ptr, avail);
	if (nread <= 0) {
		*frames = 0;
		audio_thread_rm_callback(testio->fd);
		close(testio->fd);
		testio->fd = -1;
		return 0;
	}
	buf_increment_write(testio->audbuff, nread);
	*frames = nread / testio->fmt_bytes;
	iodev->area->frames = *frames;
	cras_audio_area_config_buf_pointers(iodev->area, iodev->format,
					    write_ptr);
	*area = iodev->area;
	return nread;
}

static void update_active_node(struct cras_iodev *iodev, unsigned node_idx,
			       unsigned dev_enabled)
{
}

static void play_file_as_hotword(struct test_iodev *testio, const char *path)
{
	if (testio->fd >= 0) {
		/* Remove audio thread callback from main thread. */
		audio_thread_rm_callback_sync(
			cras_iodev_list_get_audio_thread(), testio->fd);
		close(testio->fd);
	}

	testio->fd = open(path, O_RDONLY);
	buf_reset(testio->audbuff);
}

/*
 * Exported Interface.
 */

struct cras_iodev *test_iodev_create(enum CRAS_STREAM_DIRECTION direction,
				     enum TEST_IODEV_TYPE type)
{
	struct test_iodev *testio;
	struct cras_iodev *iodev;
	struct cras_ionode *node;

	if (direction != CRAS_STREAM_INPUT || type != TEST_IODEV_HOTWORD)
		return NULL;

	testio = calloc(1, sizeof(*testio));
	if (testio == NULL)
		return NULL;
	iodev = &testio->base;
	iodev->direction = direction;
	testio->fd = -1;

	iodev->supported_rates = test_supported_rates;
	iodev->supported_channel_counts = test_supported_channel_counts;
	iodev->supported_formats = test_supported_formats;
	iodev->buffer_size = TEST_BUFFER_SIZE;

	iodev->configure_dev = configure_dev;
	iodev->close_dev = close_dev;
	iodev->frames_queued = frames_queued;
	iodev->delay_frames = delay_frames;
	if (type == TEST_IODEV_HOTWORD)
		iodev->get_buffer = get_buffer_fd_read;
	else
		iodev->get_buffer = get_buffer;
	iodev->put_buffer = put_buffer;
	iodev->update_active_node = update_active_node;

	/*
	 * Record max supported channels into cras_iodev_info.
	 * The value is the max of test_supported_channel_counts.
	 */
	iodev->info.max_supported_channels = 1;

	/* Create an empty ionode */
	node = (struct cras_ionode *)calloc(1, sizeof(*node));
	node->dev = iodev;
	node->plugged = 1;
	if (type == TEST_IODEV_HOTWORD)
		node->type = CRAS_NODE_TYPE_HOTWORD;
	else
		node->type = CRAS_NODE_TYPE_UNKNOWN;
	node->volume = 100;
	node->software_volume_needed = 0;
	node->ui_gain_scaler = 1.0f;
	strcpy(node->name, "(default)");
	cras_iodev_add_node(iodev, node);
	cras_iodev_set_active_node(iodev, node);

	/* Finally add it to the appropriate iodev list. */
	snprintf(iodev->info.name, ARRAY_SIZE(iodev->info.name), "Tester");
	iodev->info.name[ARRAY_SIZE(iodev->info.name) - 1] = '\0';
	cras_iodev_list_add_input(iodev);

	return iodev;
}

void test_iodev_destroy(struct cras_iodev *iodev)
{
	struct test_iodev *testio = (struct test_iodev *)iodev;

	cras_iodev_list_rm_input(iodev);
	free(iodev->active_node);
	cras_iodev_free_resources(iodev);
	free(testio);
}

unsigned int test_iodev_add_samples(struct test_iodev *testio, uint8_t *samples,
				    unsigned int count)
{
	unsigned int avail;
	uint8_t *write_ptr;

	write_ptr = buf_write_pointer_size(testio->audbuff, &avail);
	count = MIN(count, avail);
	memcpy(write_ptr, samples, (size_t)count * (size_t)testio->fmt_bytes);
	buf_increment_write(testio->audbuff,
			    (size_t)count * (size_t)testio->fmt_bytes);
	return count;
}

void test_iodev_command(struct cras_iodev *iodev,
			enum CRAS_TEST_IODEV_CMD command, unsigned int data_len,
			const uint8_t *data)
{
	struct test_iodev *testio = (struct test_iodev *)iodev;

	if (!cras_iodev_is_open(iodev))
		return;

	switch (command) {
	case TEST_IODEV_CMD_HOTWORD_TRIGGER:
		play_file_as_hotword(testio, (char *)data);
		break;
	default:
		break;
	}
}
