/*
 * 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 "app_shared.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)
{
	int ret;
	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.
	 */
	ret = k_mem_domain_init(&app_a_domain, ARRAY_SIZE(parts), parts);
	__ASSERT(ret == 0, "k_mem_domain_init failed %d", ret);
	ARG_UNUSED(ret);

	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.
	 *
	 * Initialize 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);
}
