/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2015,2016 Felipe F. Tonello <eu@felipetonello.com>
 *  Copyright (C) 2016 ROLI Ltd.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *
 */

#include <glib.h>

/* Avoid linkage problem on unit-tests */
#ifndef MIDI_TEST
#include "src/backtrace.h"
#define MIDI_ASSERT(_expr) btd_assert(_expr)
#else
#define MIDI_ASSERT(_expr) g_assert(_expr)
#endif
#include "libmidi.h"

inline static void buffer_append_byte(struct midi_buffer *buffer,
                                      const uint8_t byte)
{
	buffer->data[buffer->len++] = byte;
}

inline static void buffer_append_data(struct midi_buffer *buffer,
                                      const uint8_t *data, size_t size)
{
	memcpy(buffer->data + buffer->len, data, size);
	buffer->len += size;
}

inline static uint8_t buffer_reverse_get(struct midi_buffer *buffer, size_t i)
{
	MIDI_ASSERT(buffer->len > i);
	return buffer->data[buffer->len - (i + 1)];
}

inline static void buffer_reverse_set(struct midi_buffer *buffer, size_t i,
                                      const uint8_t byte)
{
	MIDI_ASSERT(buffer->len > i);
	buffer->data[buffer->len - (i + 1)] = byte;
}

inline static size_t parser_get_available_size(struct midi_write_parser *parser)
{
	return parser->stream_size - parser->midi_stream.len;
}

inline static uint8_t sysex_get(const snd_seq_event_t *ev, size_t i)
{
	MIDI_ASSERT(ev->data.ext.len > i);
	return ((uint8_t*)ev->data.ext.ptr)[i];
}

inline static void append_timestamp_high_maybe(struct midi_write_parser *parser)
{
	uint8_t timestamp_high = 0x80;

	if (midi_write_has_data(parser))
		return;

	parser->rtime = g_get_monotonic_time() / 1000; /* convert µs to ms */
	timestamp_high |= (parser->rtime & 0x1F80) >> 7;
	/* set timestampHigh */
	buffer_append_byte(&parser->midi_stream, timestamp_high);
}

inline static void append_timestamp_low(struct midi_write_parser *parser)
{
	const uint8_t timestamp_low = 0x80 | (parser->rtime & 0x7F);
	buffer_append_byte(&parser->midi_stream, timestamp_low);
}

int midi_write_init(struct midi_write_parser *parser, size_t buffer_size)
{
	int err;

	parser->rtime = 0;
	parser->rstatus = SND_SEQ_EVENT_NONE;
	parser->stream_size = buffer_size;

	parser->midi_stream.data = malloc(buffer_size);
	if (!parser->midi_stream.data)
		return -ENOMEM;

	parser->midi_stream.len = 0;

	err = snd_midi_event_new(buffer_size, &parser->midi_ev);
	if (err < 0)
		free(parser->midi_stream.data);

	return err;
}

int midi_read_init(struct midi_read_parser *parser)
{
	int err;

	parser->rstatus = 0;
	parser->rtime = -1;
	parser->timestamp = 0;
	parser->timestamp_low = 0;
	parser->timestamp_high = 0;

	parser->sysex_stream.data = malloc(MIDI_SYSEX_MAX_SIZE);
	if (!parser->sysex_stream.data)
		return -ENOMEM;

	parser->sysex_stream.len = 0;

	err = snd_midi_event_new(MIDI_MSG_MAX_SIZE, &parser->midi_ev);
	if (err < 0)
		free(parser->sysex_stream.data);

	return err;
}

/* Algorithm:
   1) check initial timestampLow:
       if used_sysex == 0, then tsLow = 1, else tsLow = 0
   2) calculate sysex size of current packet:
   2a) first check special case:
       if midi->out_length - 1 (tsHigh) - tsLow ==
          sysex_length - used_sysex
       size is: min(midi->out_length - 1 - tsLow,
                    sysex_length - used_sysex - 1)
   2b) else size is: min(midi->out_length - 1 - tsLow,
                     sysex_length - used_sysex)
   3) check if packet contains F7: fill respective tsLow byte
*/
static void read_ev_sysex(struct midi_write_parser *parser, const snd_seq_event_t *ev,
                          midi_read_ev_cb write_cb, void *user_data)
{
	unsigned int used_sysex = 0;

	/* We need at least 2 bytes (timestampLow + F0) */
	if (parser_get_available_size(parser) < 2) {
		/* send current message and start new one */
		write_cb(parser, user_data);
		midi_write_reset(parser);
		append_timestamp_high_maybe(parser);
	}

	/* timestampLow on initial F0 */
	if (sysex_get(ev, 0) == 0xF0)
		append_timestamp_low(parser);

	do {
		unsigned int size_of_sysex;

		append_timestamp_high_maybe(parser);

		size_of_sysex = MIN(parser_get_available_size(parser),
		                    ev->data.ext.len - used_sysex);

		if (parser_get_available_size(parser) == ev->data.ext.len - used_sysex)
			size_of_sysex--;

		buffer_append_data(&parser->midi_stream,
		                    ev->data.ext.ptr + used_sysex,
		                    size_of_sysex);
		used_sysex += size_of_sysex;

		if (parser_get_available_size(parser) <= 1 &&
		    buffer_reverse_get(&parser->midi_stream, 0) != 0xF7) {
			write_cb(parser, user_data);
			midi_write_reset(parser);
		}
	} while (used_sysex < ev->data.ext.len);

	/* check for F7 and update respective timestampLow byte */
	if (midi_write_has_data(parser) &&
	    buffer_reverse_get(&parser->midi_stream, 0) == 0xF7) {
		/* remove 0xF7 from buffer, append timestamp and add 0xF7 back again */
		parser->midi_stream.len--;
		append_timestamp_low(parser);
		buffer_append_byte(&parser->midi_stream, 0xF7);
	}
}

static void read_ev_others(struct midi_write_parser *parser, const snd_seq_event_t *ev,
                           midi_read_ev_cb write_cb, void *user_data)
{
	int length;

	/* check for running status */
	if (parser->rstatus != ev->type) {
		snd_midi_event_reset_decode(parser->midi_ev);
		append_timestamp_low(parser);
	}

	/* each midi message has timestampLow byte to follow */
	length = snd_midi_event_decode(parser->midi_ev,
	                               parser->midi_stream.data +
	                               parser->midi_stream.len,
	                               parser_get_available_size(parser),
	                               ev);

	if (length == -ENOMEM) {
		/* remove previously added timestampLow */
		if (parser->rstatus != ev->type)
			parser->midi_stream.len--;
		write_cb(parser, user_data);
		/* cleanup state for next packet */
		snd_midi_event_reset_decode(parser->midi_ev);
		midi_write_reset(parser);
		append_timestamp_high_maybe(parser);
		append_timestamp_low(parser);
		length = snd_midi_event_decode(parser->midi_ev,
		                               parser->midi_stream.data +
		                               parser->midi_stream.len,
		                               parser_get_available_size(parser),
		                               ev);
	}

	if (length > 0)
		parser->midi_stream.len += length;
}

void midi_read_ev(struct midi_write_parser *parser, const snd_seq_event_t *ev,
                  midi_read_ev_cb write_cb, void *user_data)
{
	MIDI_ASSERT(write_cb);

	append_timestamp_high_maybe(parser);

	/* SysEx is special case:
	   SysEx has two timestampLow bytes, before F0 and F7
	*/
	if (ev->type == SND_SEQ_EVENT_SYSEX)
		read_ev_sysex(parser, ev, write_cb, user_data);
	else
		read_ev_others(parser, ev, write_cb, user_data);

	parser->rstatus = ev->type;

	if (parser_get_available_size(parser) == 0) {
		write_cb(parser, user_data);
		midi_write_reset(parser);
	}
}

static void update_ev_timestamp(struct midi_read_parser *parser,
                                snd_seq_event_t *ev, uint16_t ts_low)
{
	int delta_timestamp;
	int delta_rtime;
	int64_t rtime_current;
	uint16_t timestamp;

	/* time_low overwflow results on time_high to increment by one */
	if (parser->timestamp_low > ts_low)
		parser->timestamp_high++;

	timestamp = (parser->timestamp_high << 7) | parser->timestamp_low;

	rtime_current = g_get_monotonic_time() / 1000; /* convert µs to ms */
	delta_timestamp = timestamp - (int)parser->timestamp;
	delta_rtime = rtime_current - parser->rtime;

	if (delta_rtime > MIDI_MAX_TIMESTAMP)
		parser->rtime = rtime_current;
	else {

		/* If delta_timestamp is way to big than delta_rtime,
		   this means that the device sent a message in the past,
		   so we have to compensate for this. */
		if (delta_timestamp > 7000 && delta_rtime < 1000)
			delta_timestamp = 0;

		/* check if timestamp did overflow */
		if (delta_timestamp < 0) {
			/* same timestamp in the past problem */
			if ((delta_timestamp + MIDI_MAX_TIMESTAMP) > 7000 &&
			    delta_rtime < 1000)
				delta_timestamp = 0;
			else
				delta_timestamp = delta_timestamp + MIDI_MAX_TIMESTAMP;
		}

		parser->rtime += delta_timestamp;
	}

	parser->timestamp += delta_timestamp;
	if (parser->timestamp > MIDI_MAX_TIMESTAMP)
		parser->timestamp %= MIDI_MAX_TIMESTAMP + 1;

	/* set event timestamp */
	/* TODO: update event timestamp here! */
}

static size_t handle_end_of_sysex(struct midi_read_parser *parser,
                                  snd_seq_event_t *ev,
                                  const uint8_t *data,
                                  size_t sysex_length)
{
	uint8_t time_low;

	/* At this time, timestampLow is copied as the last byte,
	   instead of 0xF7 */
	buffer_append_data(&parser->sysex_stream, data, sysex_length);

	time_low = buffer_reverse_get(&parser->sysex_stream, 0) & 0x7F;

	/* Remove timestamp byte */
	buffer_reverse_set(&parser->sysex_stream, 0, 0xF7);

	/* Update event */
	update_ev_timestamp(parser, ev, time_low);
	snd_seq_ev_set_sysex(ev, parser->sysex_stream.len,
	                     parser->sysex_stream.data);

	return sysex_length + 1; /* +1 because of timestampLow */
}



size_t midi_read_raw(struct midi_read_parser *parser, const uint8_t *data,
                    size_t size, snd_seq_event_t *ev /* OUT */)
{
	size_t midi_size = 0;
	size_t i = 0;
	bool err = false;

	if (parser->timestamp_high == 0)
		parser->timestamp_high = data[i++] & 0x3F;

	snd_midi_event_reset_encode(parser->midi_ev);

	/* timestamp byte */
	if (data[i] & 0x80) {
		update_ev_timestamp(parser, ev, data[i] & 0x7F);

		/* check for wrong BLE-MIDI message size */
		if (++i == size) {
			err = true;
			goto _finish;
		}
	}

	/* cleanup sysex_stream if message is broken or is a new SysEx */
	if (data[i] >= 0x80 && data[i] != 0xF7 && parser->sysex_stream.len > 0)
		parser->sysex_stream.len = 0;

	switch (data[i]) {
	case 0xF8 ... 0XFF:
		/* System Real-Time Messages */
		midi_size = 1;
		break;

		/* System Common Messages */
	case 0xF0: /* SysEx Start */ {
		uint8_t *pos;

		/* cleanup Running Status Message */
		parser->rstatus = 0;

		/* Avoid parsing if SysEx is contained in one BLE packet */
		if ((pos = memchr(data + i, 0xF7, size - i))) {
			const size_t sysex_length = pos - (data + i);
			midi_size = handle_end_of_sysex(parser, ev, data + i,
			                                sysex_length);
		} else {
			buffer_append_data(&parser->sysex_stream, data + i, size - i);
			err = true; /* Not an actual error, just incomplete message */
			midi_size = size - i;
		}

		goto _finish;
	}

	case 0xF1:
	case 0xF3:
		midi_size = 2;
		break;
	case 0xF2:
		midi_size = 3;
		break;
	case 0xF4:
	case 0xF5: /* Ignore */
		i++;
		err = true;
		goto _finish;
		break;
	case 0xF6:
		midi_size = 1;
		break;
	case 0xF7: /* SysEx End */
		buffer_append_byte(&parser->sysex_stream, 0xF7);
		snd_seq_ev_set_sysex(ev, parser->sysex_stream.len,
		                     parser->sysex_stream.data);

		midi_size = 1; /* timestampLow was alredy processed */
		goto _finish;

	case 0x80 ... 0xEF:
		/*
		 * Channel Voice Messages, Channel Mode Messages
		 * and Control Change Messages.
		 */
		parser->rstatus = data[i];
		midi_size = (data[i] >= 0xC0 && data[i] <= 0xDF) ? 2 : 3;
		break;

	case 0x00 ... 0x7F:

		/* Check for SysEx messages */
		if (parser->sysex_stream.len > 0) {
			uint8_t *pos;

			if ((pos = memchr(data + i, 0xF7, size - i))) {
				const size_t sysex_length = pos - (data + i);
				midi_size = handle_end_of_sysex(parser, ev, data + i,
				                                sysex_length);
			} else {
				buffer_append_data(&parser->sysex_stream, data + i, size - i);
				err = true; /* Not an actual error, just incomplete message */
				midi_size = size - i;
			}

			goto _finish;
		}

		/* Running State Message was not set */
		if (parser->rstatus == 0) {
			midi_size = 1;
			err = true;
			goto _finish;
		}

		snd_midi_event_encode_byte(parser->midi_ev, parser->rstatus, ev);
		midi_size = (parser->rstatus >= 0xC0 && parser->rstatus <= 0xDF) ? 1 : 2;
		break;
	}

	if ((i + midi_size) > size) {
		err = true;
		goto _finish;
	}

	snd_midi_event_encode(parser->midi_ev, data + i, midi_size, ev);

_finish:
	if (err)
		ev->type = SND_SEQ_EVENT_NONE;

	return i + midi_size;
}
