/*
 * Copyright (c) 2019 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <kernel.h>
#include <device.h>
#include <sys/libc-hooks.h>
#include <logging/log.h>

#include "sample_driver.h"
#include "main.h"
#include "app_a.h"
#include "app_syscall.h"

LOG_MODULE_REGISTER(app_a);

#define MAX_MSGS	8

/* Resource pool for allocations made by the kernel on behalf of system
 * calls. Needed for k_queue_alloc_append()
 */
K_HEAP_DEFINE(app_a_resource_pool, 256 * 5 + 128);

/* Define app_a_partition, where all globals for this app will be routed.
 * The partition starting address and size are populated by build system
 * and linker magic.
 */
K_APPMEM_PARTITION_DEFINE(app_a_partition);

/* Memory domain for application A, set up and installed in app_a_entry() */
static struct k_mem_domain app_a_domain;

/* Message queue for IPC between the driver callback and the monitor thread.
 *
 * This message queue is being statically initialized, no need to call
 * k_msgq_init() on it.
 */
K_MSGQ_DEFINE(mqueue, SAMPLE_DRIVER_MSG_SIZE, MAX_MSGS, 4);

/* Processing thread. This takes data that has been processed by application
 * B and writes it to the sample_driver, completing the control loop
 */
struct k_thread writeback_thread;
K_THREAD_STACK_DEFINE(writeback_stack, 2048);

/* Global data used by application A. By tagging with APP_A_BSS or APP_A_DATA,
 * we ensure all this gets linked into the continuous region denoted by
 * app_a_partition.
 */
APP_A_BSS const struct device *sample_device;
APP_A_BSS unsigned int pending_count;

/* ISR-level callback function. Runs in supervisor mode. Does what's needed
 * to get the data into this application's accessible memory and have the
 * worker thread running in user mode do the rest.
 */
void sample_callback(const struct device *dev, void *context, void *data)
{
	int ret;

	ARG_UNUSED(context);

	LOG_DBG("sample callback with %p", data);

	/* All the callback does is place the data payload into the
	 * message queue. This will wake up the monitor thread for further
	 * processing.
	 *
	 * We use a message queue because it will perform a data copy for us
	 * when buffering this data.
	 */
	ret = k_msgq_put(&mqueue, data, K_NO_WAIT);
	if (ret) {
		LOG_ERR("k_msgq_put failed with %d", ret);
	}
}

static void monitor_entry(void *p1, void *p2, void *p3)
{
	int ret;
	void *payload;
	unsigned int monitor_count = 0;

	ARG_UNUSED(p1);
	ARG_UNUSED(p2);
	ARG_UNUSED(p3);

	/* Monitor thread, running in user mode. Responsible for pulling
	 * data out of the message queue for further writeback.
	 */
	LOG_DBG("monitor thread entered");

	ret = sample_driver_state_set(sample_device, true);
	if (ret != 0) {
		LOG_ERR("couldn't start driver interrupts");
		k_oops();
	}

	while (monitor_count < NUM_LOOPS) {
		payload = sys_heap_alloc(&shared_pool,
					 SAMPLE_DRIVER_MSG_SIZE);
		if (payload == NULL) {
			LOG_ERR("couldn't alloc memory from shared pool");
			k_oops();
			continue;
		}

		/* Sleep waiting for some data to appear in the queue,
		 * and then copy it into the payload buffer.
		 */
		LOG_DBG("monitor thread waiting for data...");
		ret = k_msgq_get(&mqueue, payload, K_FOREVER);
		if (ret != 0) {
			LOG_ERR("k_msgq_get() failed with %d", ret);
			k_oops();
		}


		LOG_INF("monitor thread got data payload #%u", monitor_count);
		LOG_DBG("pending payloads: %u", pending_count);

		/* Put the payload in the queue for data to process by
		 * app B. This does not copy the data. Because we are using
		 * k_queue from user mode, we need to use the
		 * k_queue_alloc_append() variant, which needs to allocate
		 * some memory on the kernel side from our thread
		 * resource pool.
		 */
		pending_count++;
		k_queue_alloc_append(&shared_queue_incoming, payload);
		monitor_count++;
	}

	/* Tell the driver to stop delivering interrupts, we're closing up
	 * shop
	 */
	ret = sample_driver_state_set(sample_device, false);
	if (ret != 0) {
		LOG_ERR("couldn't disable driver");
		k_oops();
	}
	LOG_DBG("monitor thread exiting");
}

static void writeback_entry(void *p1, void *p2, void *p3)
{
	void *data;
	unsigned int writeback_count = 0;
	int ret;

	ARG_UNUSED(p1);
	ARG_UNUSED(p2);
	ARG_UNUSED(p3);

	LOG_DBG("writeback thread entered");

	while (writeback_count < NUM_LOOPS) {
		/* Grab a data payload processed by Application B,
		 * send it to the driver, and free the buffer.
		 */
		data = k_queue_get(&shared_queue_outgoing, K_FOREVER);
		if (data == NULL) {
			LOG_ERR("no data?");
			k_oops();
		}

		LOG_INF("writing processed data back to the sample device");
		sample_driver_write(sample_device, data);
		sys_heap_free(&shared_pool, data);
		pending_count--;
		writeback_count++;
	}

	/* Fairly meaningless example to show an application-defined system
	 * call being defined and used.
	 */
	ret = magic_syscall(&writeback_count);
	if (ret != 0) {
		LOG_ERR("no more magic!");
		k_oops();
	}

	LOG_DBG("writeback thread exiting");
	LOG_INF("SUCCESS");
}

/* Supervisor mode setup function for application A */
void app_a_entry(void *p1, void *p2, void *p3)
{
	struct k_mem_partition *parts[] = {
#if Z_LIBC_PARTITION_EXISTS
		&z_libc_partition,
#endif
		&app_a_partition, &shared_partition
	};

	sample_device = device_get_binding(SAMPLE_DRIVER_NAME_0);
	if (sample_device == NULL) {
		LOG_ERR("bad sample device");
		k_oops();
	}

	/* Initialize a memory domain with the specified partitions
	 * and add ourself to this domain. We need access to our own
	 * partition, the shared partition, and any common libc partition
	 * if it exists.
	 */
	k_mem_domain_init(&app_a_domain, ARRAY_SIZE(parts), parts);
	k_mem_domain_add_thread(&app_a_domain, k_current_get());

	/* Assign a resource pool to serve for kernel-side allocations on
	 * behalf of application A. Needed for k_queue_alloc_append().
	 */
	k_thread_heap_assign(k_current_get(), &app_a_resource_pool);

	/* Set the callback function for the sample driver. This has to be
	 * done from supervisor mode, as this code will run in supervisor
	 * mode in IRQ context.
	 */
	sample_driver_set_callback(sample_device, sample_callback, NULL);

	/* Set up the writeback thread, which takes processed data from
	 * application B and sends it to the sample device.
	 *
	 * This child thread automatically inherits the memory domain of
	 * this thread that created it; it will be a member of app_a_domain.
	 *
	 * Initiailize this thread with K_FOREVER timeout so we can
	 * modify its permissions and then start it.
	 */
	k_thread_create(&writeback_thread, writeback_stack,
			K_THREAD_STACK_SIZEOF(writeback_stack),
			writeback_entry, NULL, NULL, NULL,
			-1, K_USER, K_FOREVER);
	k_thread_access_grant(&writeback_thread, &shared_queue_outgoing,
			      sample_device);
	k_thread_start(&writeback_thread);

	/* We are about to drop to user mode and become the monitor thread.
	 * Grant ourselves access to the kernel objects we need for
	 * the monitor thread to function.
	 *
	 * Monitor thread needs access to the message queue shared with the
	 * ISR, and the queue to send data to the processing thread in
	 * App B.
	 */
	k_thread_access_grant(k_current_get(), &mqueue, sample_device,
			      &shared_queue_incoming);

	/* We now do a one-way transition to user mode, and will end up
	 * in monitor_thread(). We could create another thread which just
	 * starts in user mode, but this lets us re-use the current one.
	 */
	k_thread_user_mode_enter(monitor_entry, NULL, NULL, NULL);
}
