// SPDX-License-Identifier: GPL-2.0
#include <linux/console.h>
#include <linux/types.h>
#include <linux/wait.h>

#include "speakup.h"
#include "spk_priv.h"

#define SYNTH_BUF_SIZE 8192	/* currently 8K bytes */

static u16 synth_buffer[SYNTH_BUF_SIZE];	/* guess what this is for! */
static u16 *buff_in = synth_buffer;
static u16 *buff_out = synth_buffer;
static u16 *buffer_end = synth_buffer + SYNTH_BUF_SIZE - 1;

/* These try to throttle applications by stopping the TTYs
 * Note: we need to make sure that we will restart them eventually, which is
 * usually not possible to do from the notifiers. TODO: it should be possible
 * starting from linux 2.6.26.
 *
 * So we only stop when we know alive == 1 (else we discard the data anyway),
 * and the alive synth will eventually call start_ttys from the thread context.
 */
void speakup_start_ttys(void)
{
	int i;

	for (i = 0; i < MAX_NR_CONSOLES; i++) {
		if (speakup_console[i] && speakup_console[i]->tty_stopped)
			continue;
		if (vc_cons[i].d && vc_cons[i].d->port.tty)
			start_tty(vc_cons[i].d->port.tty);
	}
}
EXPORT_SYMBOL_GPL(speakup_start_ttys);

static void speakup_stop_ttys(void)
{
	int i;

	for (i = 0; i < MAX_NR_CONSOLES; i++)
		if (vc_cons[i].d && vc_cons[i].d->port.tty)
			stop_tty(vc_cons[i].d->port.tty);
}

static int synth_buffer_free(void)
{
	int chars_free;

	if (buff_in >= buff_out)
		chars_free = SYNTH_BUF_SIZE - (buff_in - buff_out);
	else
		chars_free = buff_out - buff_in;
	return chars_free;
}

int synth_buffer_empty(void)
{
	return (buff_in == buff_out);
}
EXPORT_SYMBOL_GPL(synth_buffer_empty);

void synth_buffer_add(u16 ch)
{
	if (!synth->alive) {
		/* This makes sure that we won't stop TTYs if there is no synth
		 * to restart them
		 */
		return;
	}
	if (synth_buffer_free() <= 100) {
		synth_start();
		speakup_stop_ttys();
	}
	if (synth_buffer_free() <= 1)
		return;
	*buff_in++ = ch;
	if (buff_in > buffer_end)
		buff_in = synth_buffer;
	/* We have written something to the speech synthesis, so we are not
	 * paused any more.
	 */
	spk_paused = false;
}

u16 synth_buffer_getc(void)
{
	u16 ch;

	if (buff_out == buff_in)
		return 0;
	ch = *buff_out++;
	if (buff_out > buffer_end)
		buff_out = synth_buffer;
	return ch;
}
EXPORT_SYMBOL_GPL(synth_buffer_getc);

u16 synth_buffer_peek(void)
{
	if (buff_out == buff_in)
		return 0;
	return *buff_out;
}
EXPORT_SYMBOL_GPL(synth_buffer_peek);

void synth_buffer_skip_nonlatin1(void)
{
	while (buff_out != buff_in) {
		if (*buff_out < 0x100)
			return;
		buff_out++;
		if (buff_out > buffer_end)
			buff_out = synth_buffer;
	}
}
EXPORT_SYMBOL_GPL(synth_buffer_skip_nonlatin1);

void synth_buffer_clear(void)
{
	buff_in = synth_buffer;
	buff_out = synth_buffer;
}
EXPORT_SYMBOL_GPL(synth_buffer_clear);
