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

#include <compartment.h>
#include <debug.hh>
#include <fail-simulator-on-error.h>
#include <microvium/microvium.h>
#include <platform-uart.hh>

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

namespace
{
	/**
	 * JavaScript bytecode.  The initialiser is generated by running
	 *
	 * ```
	 * microvium --output-bytes hello.js > bytecode.inc
	 * ```
	 */
	uint8_t bytecode[] =
#include "bytecode.inc"
	  ;

	/// Constant for the print function exposed to JavaScript->C++ FFI
	static constexpr mvm_HostFunctionID ImportPrint = 1;

	/// Constant for the say_hello function exposed to C++->JavaScript FFI
	static constexpr mvm_VMExportID ExportHello = 1234;

	/**
	 * Print a string passed from JavaScript.
	 */
	mvm_TeError print(mvm_VM            *vm,
	                  mvm_HostFunctionID funcID,
	                  mvm_Value         *result,
	                  mvm_Value         *args,
	                  uint8_t            argCount)
	{
		auto uart = MMIO_CAPABILITY(Uart, uart);
		// Iterate over the arguments.
		for (unsigned i = 0; i < argCount; i++)
		{
			// Coerce the argument to a string and get it as a C string
			const char *str = mvm_toStringUtf8(vm, args[i], nullptr);
			// Write each character to the UART
			for (; *str != '\0'; str++)
			{
				uart->blocking_write(*str);
			}
			// Try uncommenting the following line to see how it impacts total
			// heap usage.
			// mvm_runGC(vm, false);
		}
		// Write a trailing newline
		uart->blocking_write('\n');
		// Unconditionally return success
		return MVM_E_SUCCESS;
	}

	/**
	 * Callback from microvium that resolves imports.  This just resolves the
	 * `print` function as the import corresponding to the `ImportPrint` ID.
	 */
	mvm_TeError resolve_import(mvm_HostFunctionID  funcID,
	                           void               *context,
	                           mvm_TfHostFunction *out)
	{
		if (funcID == ImportPrint)
		{
			*out = print;
			return MVM_E_SUCCESS;
		}
		return MVM_E_UNRESOLVED_IMPORT;
	}

	/**
	 * Helper that deletes a Microvium VM when used with a C++ unique pointer.
	 */
	struct MVMDeleter
	{
		void operator()(mvm_VM *mvm) const
		{
			mvm_free(mvm);
		}
	};
} // namespace

/// Thread entry point.
void __cheri_compartment("hello") say_hello()
{
	mvm_TeError                         err;
	std::unique_ptr<mvm_VM, MVMDeleter> vm;
	// Load the JavaScript bytecode snapshot
	{
		mvm_VM *rawVm;
		err = mvm_restore(&rawVm,
		                  bytecode,
		                  sizeof(bytecode),
		                  MALLOC_CAPABILITY,
		                  ::resolve_import);
		Debug::Assert(
		  err == MVM_E_SUCCESS, "Failed to parse bytecode: {}", err);
		vm.reset(rawVm);
	}

	// Get a handle to the JavaScript `say_hello` function.
	mvm_Value sayHello;
	err = mvm_resolveExports(vm.get(), &ExportHello, &sayHello, 1);
	Debug::Assert(
	  err == MVM_E_SUCCESS, "Failed to get say_hello function: {}", err);

	// Call the function:
	err = mvm_call(vm.get(), sayHello, nullptr, nullptr, 0);
	Debug::Assert(
	  err == MVM_E_SUCCESS, "Failed to call say_hello function: {}", err);

	mvm_TsMemoryStats stats;
	// Helper lambda to report the current memory usage.
	auto reportMemory = [&]() {
		mvm_getMemoryStats(vm.get(), &stats);
		Debug::log(
		  "Microvium is using {} bytes of memory, including {} bytes of heap",
		  stats.totalSize,
		  stats.virtualHeapUsed);
	};

	// See how much memory is used at the end of the invocation
	reportMemory();

	// Run the GC to shrink the heap as much as possible and report usage.
	Debug::log("Running GC");
	mvm_runGC(vm.get(), true);
	reportMemory();

	// Report the peak usage
	Debug::log("Peak heap used: {} bytes, peak stack used: {} bytes",
	           stats.virtualHeapHighWaterMark,
	           stats.stackHighWaterMark);
}
