// Copyright Microsoft and CHERIoT Contributors.
// SPDX-License-Identifier: MIT

#include "microvium-ffi.hh"
#include "secret.h"
#include <compartment.h>
#include <cstdint>
#include <cstdlib>
#include <debug.hh>
#include <riscvreg.h>
#include <type_traits>
#include <vector>

/// Expose debugging features unconditionally for this compartment.
using Debug = ConditionalDebug<true, "JavaScript compartment">;
using CHERI::Capability;

/// Thread entry point.
void __cheri_compartment("js") run()
{
	// Set the secret value on startup.
	set_secret();

	while (true)
	{
		// Get a capability to the UART.
		auto uart = MMIO_CAPABILITY(Uart, uart);
		// Create a vector to hold the bytecode.
		std::vector<uint8_t> bytecode;
		// Helper that reads a character and errors if it isn't the expected
		// one.
		auto skip = [&](char byte) {
			char c = uart->blocking_read();
			Debug::Assert(byte == c, "Read '{}', expected '{}'", c, byte);
		};
		// Helper that reads from the UART until a specific character is seen
		auto skipUntil = [&](char byte) {
			while (uart->blocking_read() != byte) {}
		};
		// Helper that converts a hex character to an integer.  Returns 0 on
		// invalid values.
		auto hexByteToNumber = [](char c) {
			switch (c)
			{
				case '0' ... '9':
					return c - '0';
				case 'a' ... 'f':
					return c - 'a' + 10;
				case 'A' ... 'F':
					return c - 'A' + 10;
			}
			return 0;
		};

		// Read values in the form generated by microvium's hex output: a
		// series of hex bytes in braces.
		skipUntil('{');
		while (true)
		{
			skip('0');
			skip('x');
			uint8_t byte = hexByteToNumber(uart->blocking_read()) << 4;
			byte += hexByteToNumber(uart->blocking_read());
			bytecode.push_back(byte);
			char c = uart->blocking_read();
			if (c == '}')
			{
				break;
			}
			Debug::Assert(c == ',', "Expected comma or close brace, read {}", c);
		}

		Debug::log("Read {} bytes of bytecode", bytecode.size());
		Debug::log("{} bytes of heap available",
		           heap_quota_remaining(MALLOC_CAPABILITY));

		////////////////////////////////////////////////////////////////////////
		// We've now read the bytecode into a buffer.  Spin up the JavaScript
		// VM to execute it.
		////////////////////////////////////////////////////////////////////////

		// Allocate the space for the VM capability registers on the stack and
		// record its location.
		// **Note**: This must be on the stack and in same compartment as the
		// JavaScript interpreter, so that the callbacks can re-derive it from
		// csp.
		AttackerRegisterState state;
		attackerRegisterStateAddress = Capability{&state}.address();

		mvm_TeError                         err;
		std::unique_ptr<mvm_VM, MVMDeleter> vm;
		// Create a Microvium VM from the bytecode.
		{
			mvm_VM *rawVm;
			err = mvm_restore(
			  &rawVm,            /* Out pointer to the VM */
			  bytecode.data(),   /* Bytecode data */
			  bytecode.size(),   /* Bytecode length */
			  MALLOC_CAPABILITY, /* Capability used to allocate memory */
			  ::resolve_import); /* Callback used to resolve FFI imports */
			// If this is not valid bytecode, give up.
			Debug::Assert(
			  err == MVM_E_SUCCESS, "Failed to parse bytecode: {}", err);
			vm.reset(rawVm);
		}

		// Get a handle to the JavaScript `run` function.
		mvm_Value run;
		err = mvm_resolveExports(vm.get(), &ExportRun, &run, 1);
		if (err != MVM_E_SUCCESS)
		{
			Debug::log("Failed to get run function: {}", err);
		}
		else
		{
			// Call the function:
			err = mvm_call(vm.get(), run, nullptr, nullptr, 0);
			if (err != MVM_E_SUCCESS)
			{
				Debug::log("Failed to call run function: {}", err);
			}
		}
	}
}
