/*
 * Copyright (c) 2019 Oticon A/S
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

#include "edtt_driver.h"
#include <zephyr/kernel.h>
#include "posix_native_task.h"

#include "bs_tracing.h"
#include "bs_utils.h"
#include "bs_oswrap.h"
#include "bs_pc_base_fifo_user.h"

/* Recheck if something arrived from the EDTT every 5ms */
#define EDTT_IF_RECHECK_DELTA 5 /* ms */

/* We want the runs to be deterministic => we want to resync with the Phy
 * before we retry any read so the EDTT may also run
 */
#define EDTT_SIMU_RESYNC_TIME_WITH_EDTT \
	(EDTT_IF_RECHECK_DELTA * MSEC_PER_SEC - 1)

int edtt_mode_enabled;

/* In this mode, when the EDTTool closes the FIFO we automatically terminate
 * this simulated device. If false, we just continue running
 */
static int edtt_autoshutdown;

#define TO_DEVICE 0
#define TO_EDTT   1
static int fifo[2] = { -1, -1 };
static char *fifo_path[2] = {NULL, NULL};

extern unsigned int global_device_nbr;

static void edttd_clean_up(void);
static void edptd_create_fifo_if(void);
static int fifo_low_level_read(uint8_t *bufptr, int size);

bool edtt_start(void)
{
	if (edtt_mode_enabled == false) {
		/* otherwise we don't try to open the EDTT interface */
		return true;
	}

	edptd_create_fifo_if();

	extern void tm_set_phy_max_resync_offset(uint64_t offset_in_us);
	tm_set_phy_max_resync_offset(EDTT_SIMU_RESYNC_TIME_WITH_EDTT);
	return true;
}

void edtt_stop(void)
{
	if (edtt_mode_enabled == false) {
		/* otherwise we don't try to open the EDTT interface */
		return;
	}

	bs_trace_raw(9, "EDTTT: %s called\n", __func__);
	edttd_clean_up();
	edtt_mode_enabled = false;
}

#if defined(NATIVE_TASK)
NATIVE_TASK(edtt_stop, ON_EXIT, 1);
#endif

/**
 * Attempt to read size bytes thru the EDTT IF into the buffer <*ptr>
 * <flags> can be set to EDTTT_BLOCK or EDTTT_NONBLOCK
 *
 * If set to EDTTT_BLOCK it will block the calling thread until <size>
 * bytes have been read or the interface has been closed.
 * If set to EDTTT_NONBLOCK it returns as soon as there is no more data to be
 * read
 *
 * Returns the amount of read bytes, or -1 on error
 */
int edtt_read(uint8_t *ptr, size_t size, int flags)
{
	if (edtt_mode_enabled == false) {
		return -1;
	}

	bs_trace_raw_time(8, "EDTT: Asked to read %i bytes\n", size);
	int read = 0;

	while (size > 0) {
		int received_bytes;

		received_bytes = fifo_low_level_read(ptr, size);
		if (received_bytes < 0) {
			return -1;
		} else if (received_bytes > 0) {
			size -= received_bytes;
			ptr += received_bytes;
			read += received_bytes;
		} else {
			if (flags & EDTTT_BLOCK) {
				bs_trace_raw_time(9, "EDTT: No enough data yet,"
						"sleeping for %i ms\n",
						EDTT_IF_RECHECK_DELTA);
				k_sleep(K_MSEC(EDTT_IF_RECHECK_DELTA));
			} else {
				bs_trace_raw_time(9, "EDTT: No enough data yet,"
						"returning\n");
				break;
			}
		}
	}

	return read;
}

/**
 * Write <size> bytes from <ptr> toward the EDTTool
 *
 * <flags> is ignored in this driver, all writes to the tool are
 * instantaneous
 */
int edtt_write(uint8_t *ptr, size_t size, int flags)
{
	if (edtt_mode_enabled == false) {
		return -1;
	}
	bs_trace_raw_time(9, "EDTT: Asked to write %i bytes\n", size);

	if (write(fifo[TO_EDTT], ptr, size) != size) {
		if (errno == EPIPE) {
			bs_trace_error_line("EDTT IF suddenly closed by other "
					    "end\n");
		}
		if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
			bs_trace_error_line("EDTT IF filled up (FIFO "
					    "size needs to be increased)\n");
		}
		bs_trace_error_line("EDTT IF: Unexpected error on write\n");
	}
	return size;
}

/*
 * Applications may want to enable the EDTT interface only in some
 * cases. By default it is not enabled in this driver. This function
 * must be called once before starting it to do so
 */
void enable_edtt_mode(void)
{
	edtt_mode_enabled = true;
}

/**
 * Automatically terminate this device execution once the EDTTool disconnects
 */
void set_edtt_autoshutdown(bool Mode)
{
	edtt_autoshutdown = Mode;
}

static void edptd_create_fifo_if(void)
{
	int flags;

	bs_trace_raw_time(9, "Bringing EDTT IF up (waiting for other side)\n");

	if (pb_com_path == NULL) {
		bs_trace_error_line("Not connected to Phy."
				    "EDTT IF cannot be brought up\n");
	}

	/* At this point we have connected to the Phy so the COM folder does
	 * already exist
	 * also SIGPIPE is already ignored
	 */

	fifo_path[TO_DEVICE] = (char *)bs_calloc(pb_com_path_length + 30,
						 sizeof(char));
	fifo_path[TO_EDTT] = (char *)bs_calloc(pb_com_path_length + 30,
						 sizeof(char));
	sprintf(fifo_path[TO_DEVICE], "%s/Device%i.PTTin",
		pb_com_path, global_device_nbr);
	sprintf(fifo_path[TO_EDTT], "%s/Device%i.PTTout",
		pb_com_path, global_device_nbr);

	if ((pb_create_fifo_if_not_there(fifo_path[TO_DEVICE]) != 0)
		|| (pb_create_fifo_if_not_there(fifo_path[TO_EDTT]) != 0)) {
		bs_trace_error_line("Couldn't create FIFOs for EDTT IF\n");
	}

	/* we block here until the EDTT opens its end */
	fifo[TO_EDTT] = open(fifo_path[TO_EDTT], O_WRONLY);
	if (fifo[TO_EDTT] == -1) {
		bs_trace_error_line("Couldn't create FIFOs for EDTT IF\n");
	}

	flags = fcntl(fifo[TO_EDTT], F_GETFL);
	flags |= O_NONBLOCK;
	fcntl(fifo[TO_EDTT], F_SETFL, flags);

	/* we will block here until the EDTT opens its end */
	fifo[TO_DEVICE] = open(fifo_path[TO_DEVICE], O_RDONLY);
	if (fifo[TO_DEVICE] == -1) {
		bs_trace_error_line("Couldn't create FIFOs for EDTT IF\n");
	}

	flags = fcntl(fifo[TO_DEVICE], F_GETFL);
	flags |= O_NONBLOCK;
	fcntl(fifo[TO_DEVICE], F_SETFL, flags);
}

static void edttd_clean_up(void)
{
	for (int dir = TO_DEVICE ; dir <= TO_EDTT ; dir++) {
		if (fifo_path[dir]) {
			if (fifo[dir] != -1) {
				close(fifo[dir]);
				remove(fifo_path[dir]);
				fifo[dir] = -1;
			}
			free(fifo_path[dir]);
			fifo_path[dir] = NULL;
		}
	}
	if (pb_com_path != NULL) {
		rmdir(pb_com_path);
	}
}

static int fifo_low_level_read(uint8_t *bufptr, int size)
{
	int received_bytes = read(fifo[TO_DEVICE], bufptr, size);

	if ((received_bytes == -1) && (errno == EAGAIN)) {
		return 0;
	} else if (received_bytes == EOF || received_bytes == 0) {
		/*The FIFO was closed by the EDTT*/
		if (edtt_autoshutdown) {
			bs_trace_raw_time(3, "EDTT: FIFO closed "
					"(ptt_autoshutdown==true) =>"
					" Terminate\n");
			edttd_clean_up();
			bs_trace_exit_line("\n");
		} else {
			bs_trace_raw_time(3, "EDTT: FIFO closed "
					"(ptt_autoshutdown==false) => We close "
					"the FIFOs and move on\n");
			edttd_clean_up();
			edtt_mode_enabled = false;
			return -1;
		}
	} else if (received_bytes == -1) {
		bs_trace_error_line("EDTT: Unexpected error\n");
	}

	return received_bytes;
}
