/*
 * 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_MEM_POOL_DEFINE(app_a_resource_pool, 32, 256, 5, 4);

/* 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 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(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_mem_pool_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_mem_pool_free(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_resource_pool_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);
}

