/*
 * Copyright (C) 2014 Intel Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <pthread.h>
#include <unistd.h>
#include <math.h>

#include "if-main.h"
#include "../hal-utils.h"

audio_hw_device_t *if_audio_sco = NULL;
static struct audio_stream_out *stream_out = NULL;
static struct audio_stream_in *stream_in = NULL;

static size_t buffer_size = 0;
static size_t buffer_size_in = 0;
static pthread_t play_thread = 0;
static pthread_mutex_t outstream_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t state_mutex = PTHREAD_MUTEX_INITIALIZER;

enum state {
	STATE_STOPPED,
	STATE_STOPPING,
	STATE_PLAYING,
	STATE_SUSPENDED,
	STATE_MAX
};

SINTMAP(audio_channel_mask_t, -1, "(AUDIO_CHANNEL_INVALID)")
	DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT),
	DELEMENT(AUDIO_CHANNEL_OUT_FRONT_RIGHT),
	DELEMENT(AUDIO_CHANNEL_OUT_FRONT_CENTER),
	DELEMENT(AUDIO_CHANNEL_OUT_LOW_FREQUENCY),
	DELEMENT(AUDIO_CHANNEL_OUT_BACK_LEFT),
	DELEMENT(AUDIO_CHANNEL_OUT_BACK_RIGHT),
	DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER),
	DELEMENT(AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER),
	DELEMENT(AUDIO_CHANNEL_OUT_BACK_CENTER),
	DELEMENT(AUDIO_CHANNEL_OUT_SIDE_LEFT),
	DELEMENT(AUDIO_CHANNEL_OUT_SIDE_RIGHT),
	DELEMENT(AUDIO_CHANNEL_OUT_TOP_CENTER),
	DELEMENT(AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT),
	DELEMENT(AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER),
	DELEMENT(AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT),
	DELEMENT(AUDIO_CHANNEL_OUT_TOP_BACK_LEFT),
	DELEMENT(AUDIO_CHANNEL_OUT_TOP_BACK_CENTER),
	DELEMENT(AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT),
	DELEMENT(AUDIO_CHANNEL_OUT_MONO),
	DELEMENT(AUDIO_CHANNEL_OUT_STEREO),
	DELEMENT(AUDIO_CHANNEL_OUT_QUAD),
	DELEMENT(AUDIO_CHANNEL_OUT_SURROUND),
	DELEMENT(AUDIO_CHANNEL_OUT_5POINT1),
	DELEMENT(AUDIO_CHANNEL_OUT_7POINT1),
	DELEMENT(AUDIO_CHANNEL_OUT_ALL),
	DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT),
	DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT),
	DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT),
	DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT),
	DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT),
ENDMAP

SINTMAP(audio_format_t, -1, "(AUDIO_FORMAT_INVALID)")
	DELEMENT(AUDIO_FORMAT_DEFAULT),
	DELEMENT(AUDIO_FORMAT_PCM),
	DELEMENT(AUDIO_FORMAT_MP3),
	DELEMENT(AUDIO_FORMAT_AMR_NB),
	DELEMENT(AUDIO_FORMAT_AMR_WB),
	DELEMENT(AUDIO_FORMAT_AAC),
	DELEMENT(AUDIO_FORMAT_HE_AAC_V1),
	DELEMENT(AUDIO_FORMAT_HE_AAC_V2),
	DELEMENT(AUDIO_FORMAT_VORBIS),
	DELEMENT(AUDIO_FORMAT_MAIN_MASK),
	DELEMENT(AUDIO_FORMAT_SUB_MASK),
	DELEMENT(AUDIO_FORMAT_PCM_16_BIT),
	DELEMENT(AUDIO_FORMAT_PCM_8_BIT),
	DELEMENT(AUDIO_FORMAT_PCM_32_BIT),
	DELEMENT(AUDIO_FORMAT_PCM_8_24_BIT),
ENDMAP

static int current_state = STATE_STOPPED;

#define SAMPLERATE 44100
static short sample[SAMPLERATE];
static uint16_t sample_pos;

static void init_p(int argc, const char **argv)
{
	int err;
	const hw_module_t *module;
	audio_hw_device_t *device;

	err = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, "sco", &module);
	if (err) {
		haltest_error("hw_get_module_by_class returned %d\n", err);
		return;
	}

	err = audio_hw_device_open(module, &device);
	if (err) {
		haltest_error("audio_hw_device_open returned %d\n", err);
		return;
	}

	if_audio_sco = device;
}

static int feed_from_file(short *buffer, void *data)
{
	FILE *in = data;
	return fread(buffer, buffer_size, 1, in);
}

static int feed_from_generator(short *buffer, void *data)
{
	size_t i = 0;
	float volume = 0.5;
	float *freq = data;
	float f = 1;

	if (freq)
		f = *freq;

	/* buffer_size is in bytes but we are using buffer of shorts (2 bytes)*/
	for (i = 0; i < buffer_size / sizeof(*buffer) - 1;) {
		if (sample_pos >= SAMPLERATE)
			sample_pos = sample_pos % SAMPLERATE;

		/* Use the same sample for both channels */
		buffer[i++] = sample[sample_pos] * volume;
		buffer[i++] = sample[sample_pos] * volume;

		sample_pos += f;
	}

	return buffer_size;
}

static int feed_from_in(short *buffer, void *data)
{
	return stream_in->read(stream_in, buffer, buffer_size_in);
}

static void prepare_sample(void)
{
	int x;
	double s;

	haltest_info("Preparing audio sample...\n");

	for (x = 0; x < SAMPLERATE; x++) {
		/* prepare sinusoidal 1Hz sample */
		s = (2.0 * 3.14159) * ((double)x / SAMPLERATE);
		s = sin(s);

		/* remap <-1, 1> to signed 16bit PCM range */
		sample[x] = s * 32767;
	}

	sample_pos = 0;
}

static void mono_to_stereo_pcm16(const int16_t *in, int16_t *out, size_t samples)
{
	size_t i;

	for (i = 0; i < samples; i++) {
		out[2 * i] = in[i];
		out[2 * i + 1] = in[i];
	}
}

static void *playback_thread(void *data)
{
	int (*filbuff_cb) (short*, void*);
	short buffer[buffer_size / sizeof(short)];
	short buffer_in[buffer_size_in / sizeof(short)];
	size_t len = 0;
	ssize_t w_len = 0;
	FILE *in = data;
	void *cb_data = NULL;
	float freq = 440.0;

	/* Use file or fall back to generator */
	if (in) {
		if (data == stream_in)
			filbuff_cb = feed_from_in;
		else {
			filbuff_cb = feed_from_file;
			cb_data = in;
		}
	} else {
		prepare_sample();
		filbuff_cb = feed_from_generator;
		cb_data = &freq;
	}

	pthread_mutex_lock(&state_mutex);
	current_state = STATE_PLAYING;
	pthread_mutex_unlock(&state_mutex);

	do {
		pthread_mutex_lock(&state_mutex);

		if (current_state == STATE_STOPPING) {
			haltest_info("Detected stopping\n");
			pthread_mutex_unlock(&state_mutex);
			break;
		} else if (current_state == STATE_SUSPENDED) {
			pthread_mutex_unlock(&state_mutex);
			usleep(500);
			continue;
		}

		pthread_mutex_unlock(&state_mutex);

		if (data && data == stream_in) {
			int chan_in = popcount(stream_in->common.get_channels(&stream_in->common));
			int chan_out = popcount(stream_out->common.get_channels(&stream_out->common));

			len = filbuff_cb(buffer_in, cb_data);

			if (chan_in == 1 && chan_out == 2) {
				mono_to_stereo_pcm16(buffer_in,
							buffer,
							buffer_size_in / 2);
			}
		} else
			len = filbuff_cb(buffer, cb_data);

		pthread_mutex_lock(&outstream_mutex);
		if (!stream_out) {
			pthread_mutex_unlock(&outstream_mutex);
			break;
		}

		w_len = stream_out->write(stream_out, buffer, buffer_size);
		pthread_mutex_unlock(&outstream_mutex);
	} while (len && w_len > 0);

	if (in && data != stream_in)
		fclose(in);

	pthread_mutex_lock(&state_mutex);
	current_state = STATE_STOPPED;
	pthread_mutex_unlock(&state_mutex);

	haltest_info("Done playing.\n");

	return NULL;
}

static void write_stereo_pcm16(const short *input, size_t len, FILE *out)
{
	short sample[2];
	size_t i;

	for (i = 0; i < len / 2; i++) {
		sample[0] = input[i];
		sample[1] = input[i];

		fwrite(sample, sizeof(sample), 1, out);
	}
}

static void *read_thread(void *data)
{
	int (*filbuff_cb) (short*, void*) = feed_from_in;
	short buffer[buffer_size_in / sizeof(short)];
	ssize_t len = 0;
	void *cb_data = NULL;
	FILE *out = data;

	pthread_mutex_lock(&state_mutex);
	current_state = STATE_PLAYING;
	pthread_mutex_unlock(&state_mutex);

	do {
		pthread_mutex_lock(&state_mutex);

		if (current_state == STATE_STOPPING) {
			haltest_info("Detected stopping\n");
			pthread_mutex_unlock(&state_mutex);
			break;
		} else if (current_state == STATE_SUSPENDED) {
			pthread_mutex_unlock(&state_mutex);
			usleep(500);
			continue;
		}

		pthread_mutex_unlock(&state_mutex);

		len = filbuff_cb(buffer, cb_data);
		if (len < 0) {
			haltest_error("Error receiving SCO data");
			break;
		}

		haltest_info("Read %zd bytes\n", len);

		if (out) {
			write_stereo_pcm16(buffer, len, out);
			haltest_info("Written %zd bytes\n", len * 2);
		}
	} while (len);

	if (out)
		fclose(out);

	pthread_mutex_lock(&state_mutex);
	current_state = STATE_STOPPED;
	pthread_mutex_unlock(&state_mutex);

	haltest_info("Done reading.\n");

	return NULL;
}

static void play_p(int argc, const char **argv)
{
	const char *fname = NULL;
	FILE *in = NULL;

	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	if (argc < 3) {
		haltest_error("Invalid audio file path.\n");
		haltest_info("Using sound generator.\n");
	} else {
		fname = argv[2];
		in = fopen(fname, "r");

		if (in == NULL) {
			haltest_error("Cannot open file: %s\n", fname);
			return;
		}
		haltest_info("Playing file: %s\n", fname);
	}

	if (buffer_size == 0) {
		haltest_error("Invalid buffer size. Was stream_out opened?\n");
		goto fail;
	}

	pthread_mutex_lock(&state_mutex);
	if (current_state != STATE_STOPPED) {
		haltest_error("Already playing or stream suspended!\n");
		pthread_mutex_unlock(&state_mutex);
		goto fail;
	}
	pthread_mutex_unlock(&state_mutex);

	if (pthread_create(&play_thread, NULL, playback_thread, in) != 0) {
		haltest_error("Cannot create playback thread!\n");
		goto fail;
	}

	return;
fail:
	if (in)
		fclose(in);
}

static void loop_p(int argc, const char **argv)
{
	int chan_out, chan_in;

	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);
	RETURN_IF_NULL(stream_in);

	chan_out = popcount(stream_out->common.get_channels(&stream_out->common));
	chan_in = popcount(stream_in->common.get_channels(&stream_in->common));

	if (!buffer_size || !buffer_size_in) {
		haltest_error("Invalid buffer sizes. Streams opened\n");
		return;
	}

	if (buffer_size / chan_out != buffer_size_in / chan_in) {
		haltest_error("read/write buffers differ, not supported\n");
		return;
	}

	pthread_mutex_lock(&state_mutex);
	if (current_state != STATE_STOPPED) {
		haltest_error("Already playing or stream suspended!\n");
		pthread_mutex_unlock(&state_mutex);
		return;
	}
	pthread_mutex_unlock(&state_mutex);

	if (pthread_create(&play_thread, NULL, playback_thread,
							stream_in) != 0)
		haltest_error("Cannot create playback thread!\n");
}

static void read_p(int argc, const char **argv)
{
	const char *fname = NULL;
	FILE *out = NULL;

	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_in);

	pthread_mutex_lock(&state_mutex);
	if (current_state != STATE_STOPPED) {
		haltest_error("Already playing or stream suspended!\n");
		pthread_mutex_unlock(&state_mutex);
		return;
	}
	pthread_mutex_unlock(&state_mutex);

	if (argc < 3) {
		haltest_error("Invalid audio file path.\n");
		haltest_info("Using read and through away\n");
	} else {
		fname = argv[2];
		out = fopen(fname, "w");
		if (!out) {
			haltest_error("Cannot open file: %s\n", fname);
			return;
		}

		haltest_info("Reading to file: %s\n", fname);
	}

	if (!buffer_size_in) {
		haltest_error("Invalid buffer size.\n");
		goto failed;
	}

	if (pthread_create(&play_thread, NULL, read_thread, out) != 0) {
		haltest_error("Cannot create playback thread!\n");
		goto failed;
	}

	return;
failed:
	if (out)
		fclose(out);
}

static void stop_p(int argc, const char **argv)
{
	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(play_thread);

	pthread_mutex_lock(&state_mutex);
	if (current_state == STATE_STOPPED || current_state == STATE_STOPPING) {
		pthread_mutex_unlock(&state_mutex);
		return;
	}

	if (stream_out) {
		pthread_mutex_lock(&outstream_mutex);
		stream_out->common.standby(&stream_out->common);
		pthread_mutex_unlock(&outstream_mutex);
	}

	current_state = STATE_STOPPING;
	pthread_mutex_unlock(&state_mutex);

	pthread_join(play_thread, NULL);
	play_thread = 0;

	haltest_info("Ended %s\n", __func__);
}

static void open_output_stream_p(int argc, const char **argv)
{
	struct audio_config *config;
	int err;

	RETURN_IF_NULL(if_audio_sco);

	pthread_mutex_lock(&state_mutex);
	if (current_state == STATE_PLAYING) {
		haltest_error("Already playing!\n");
		pthread_mutex_unlock(&state_mutex);
		return;
	}
	pthread_mutex_unlock(&state_mutex);

	if (argc < 3) {
		haltest_info("No sampling rate specified. Use default conf\n");
		config = NULL;
	} else {
		config = calloc(1, sizeof(struct audio_config));
		if (!config)
			return;

		config->sample_rate = atoi(argv[2]);
		config->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
		config->format = AUDIO_FORMAT_PCM_16_BIT;
	}

	err = if_audio_sco->open_output_stream(if_audio_sco,
						0,
						AUDIO_DEVICE_OUT_ALL_SCO,
						AUDIO_OUTPUT_FLAG_NONE,
						config,
						&stream_out);
	if (err < 0) {
		haltest_error("open output stream returned %d\n", err);
		goto failed;
	}

	buffer_size = stream_out->common.get_buffer_size(&stream_out->common);
	if (buffer_size == 0)
		haltest_error("Invalid buffer size received!\n");
	else
		haltest_info("Using buffer size: %zu\n", buffer_size);
failed:
	if (config)
		free(config);
}

static void close_output_stream_p(int argc, const char **argv)
{
	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	if (play_thread)
		stop_p(argc, argv);

	if_audio_sco->close_output_stream(if_audio_sco, stream_out);

	stream_out = NULL;
	buffer_size = 0;
}

static void open_input_stream_p(int argc, const char **argv)
{
	struct audio_config *config;
	int err;

	RETURN_IF_NULL(if_audio_sco);

	pthread_mutex_lock(&state_mutex);
	if (current_state == STATE_PLAYING) {
		haltest_error("Already playing!\n");
		pthread_mutex_unlock(&state_mutex);
		return;
	}
	pthread_mutex_unlock(&state_mutex);

	if (argc < 3) {
		haltest_info("No sampling rate specified. Use default conf\n");
		config = NULL;
	} else {
		config = calloc(1, sizeof(struct audio_config));
		if (!config)
			return;

		config->sample_rate = atoi(argv[2]);
		config->channel_mask = AUDIO_CHANNEL_OUT_MONO;
		config->format = AUDIO_FORMAT_PCM_16_BIT;
	}

	err = if_audio_sco->open_input_stream(if_audio_sco,
						0,
						AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
						config,
						&stream_in);
	if (err < 0) {
		haltest_error("open output stream returned %d\n", err);
		goto failed;
	}

	buffer_size_in = stream_in->common.get_buffer_size(&stream_in->common);
	if (buffer_size_in == 0)
		haltest_error("Invalid buffer size received!\n");
	else
		haltest_info("Using buffer size: %zu\n", buffer_size_in);
failed:
	if (config)
		free(config);
}

static void close_input_stream_p(int argc, const char **argv)
{
	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_in);

	if (play_thread)
		stop_p(argc, argv);

	if_audio_sco->close_input_stream(if_audio_sco, stream_in);

	stream_in = NULL;
	buffer_size_in = 0;
}

static void cleanup_p(int argc, const char **argv)
{
	int err;

	RETURN_IF_NULL(if_audio_sco);

	pthread_mutex_lock(&state_mutex);
	if (current_state != STATE_STOPPED) {
		pthread_mutex_unlock(&state_mutex);
		close_output_stream_p(0, NULL);
	} else {
		pthread_mutex_unlock(&state_mutex);
	}

	err = audio_hw_device_close(if_audio_sco);
	if (err < 0) {
		haltest_error("audio_hw_device_close returned %d\n", err);
		return;
	}

	if_audio_sco = NULL;
}

static void suspend_p(int argc, const char **argv)
{
	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	pthread_mutex_lock(&state_mutex);
	if (current_state != STATE_PLAYING) {
		pthread_mutex_unlock(&state_mutex);
		return;
	}
	current_state = STATE_SUSPENDED;
	pthread_mutex_unlock(&state_mutex);

	pthread_mutex_lock(&outstream_mutex);
	stream_out->common.standby(&stream_out->common);
	pthread_mutex_unlock(&outstream_mutex);
}

static void resume_p(int argc, const char **argv)
{
	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	pthread_mutex_lock(&state_mutex);
	if (current_state == STATE_SUSPENDED)
		current_state = STATE_PLAYING;
	pthread_mutex_unlock(&state_mutex);
}

static void get_latency_p(int argc, const char **argv)
{
	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	haltest_info("Output audio stream latency: %d\n",
					stream_out->get_latency(stream_out));
}

static void get_buffer_size_p(int argc, const char **argv)
{
	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	haltest_info("Current output buffer size: %zu\n",
		stream_out->common.get_buffer_size(&stream_out->common));
}

static void get_channels_p(int argc, const char **argv)
{
	audio_channel_mask_t channels;

	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	channels = stream_out->common.get_channels(&stream_out->common);

	haltest_info("Channels: %s\n", audio_channel_mask_t2str(channels));
}

static void get_format_p(int argc, const char **argv)
{
	audio_format_t format;

	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	format = stream_out->common.get_format(&stream_out->common);

	haltest_info("Format: %s\n", audio_format_t2str(format));
}

static void get_sample_rate_p(int argc, const char **argv)
{
	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	haltest_info("Current sample rate: %d\n",
		stream_out->common.get_sample_rate(&stream_out->common));
}

static void get_parameters_p(int argc, const char **argv)
{
	const char *keystr;

	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	if (argc < 3) {
		haltest_info("No keys given.\n");
		keystr = "";
	} else {
		keystr = argv[2];
	}

	haltest_info("Current parameters: %s\n",
			stream_out->common.get_parameters(&stream_out->common,
								keystr));
}

static void set_parameters_p(int argc, const char **argv)
{
	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	if (argc < 3) {
		haltest_error("No key=value; pairs given.\n");
		return;
	}

	stream_out->common.set_parameters(&stream_out->common, argv[2]);
}

static void set_sample_rate_p(int argc, const char **argv)
{
	RETURN_IF_NULL(if_audio_sco);
	RETURN_IF_NULL(stream_out);

	if (argc < 3)
		return;

	stream_out->common.set_sample_rate(&stream_out->common, atoi(argv[2]));
}

static void init_check_p(int argc, const char **argv)
{
	RETURN_IF_NULL(if_audio_sco);

	haltest_info("Init check result: %d\n",
					if_audio_sco->init_check(if_audio_sco));
}

static struct method methods[] = {
	STD_METHOD(init),
	STD_METHOD(cleanup),
	STD_METHODH(open_output_stream, "sample_rate"),
	STD_METHOD(close_output_stream),
	STD_METHODH(open_input_stream, "sampling rate"),
	STD_METHOD(close_input_stream),
	STD_METHODH(play, "<path to pcm file>"),
	STD_METHOD(read),
	STD_METHOD(loop),
	STD_METHOD(stop),
	STD_METHOD(suspend),
	STD_METHOD(resume),
	STD_METHOD(get_latency),
	STD_METHOD(get_buffer_size),
	STD_METHOD(get_channels),
	STD_METHOD(get_format),
	STD_METHOD(get_sample_rate),
	STD_METHODH(get_parameters, "<closing>"),
	STD_METHODH(set_parameters, "<closing=value>"),
	STD_METHODH(set_sample_rate, "<sample rate>"),
	STD_METHOD(init_check),
	END_METHOD
};

const struct interface sco_if = {
	.name = "sco",
	.methods = methods
};
