#include <MSFS\MSFS.h>
#include <MSFS\Legacy\gauges.h>
#include <MSFS\MSFS_CommBus.h>

#include <string>
#include <vector>
#include <iterator>

#include <string.h>
#include <dirent.h> 
#include <stdio.h>
#include <stdlib.h>

#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"

#include "FileSystem.hpp"
#include "Utils.hpp"

#include "Constants.h"

static void CommandWasmCallback(const char* args, unsigned int size, void* ctx);

extern "C"
{
	MSFS_CALLBACK void module_init(void)
	{
		khofmann::log(stdout, "[PDF-Reader Module] Starting init\n");

		khofmann::logFile = fopen("/work/log.txt", "w");
		if (khofmann::logFile == NULL)
		{
			khofmann::log(stderr, "[PDF-Reader Module] Error creating logfile\n");
		}

		if (!fsCommBusRegister(COMMANDS, CommandWasmCallback))
		{
			khofmann::log(stderr, "[PDF-Reader Module] Error registering command CommBus\n");
		}

		khofmann::log(stdout, "[PDF-Reader Module] Inited\n");
	}

	extern "C" MSFS_CALLBACK void module_deinit(void)
	{
		khofmann::log(stdout, "[PDF-Reader Module] Starting deinit\n");

		int c = fsCommBusUnregister(COMMANDS, CommandWasmCallback);
		khofmann::log(stdout, "%i unregistered", &c);

		khofmann::log(stdout, "[PDF-Reader Module] Deinited\n");

		fclose(khofmann::logFile);
	}

	static void CommandWasmCallback(const char* args, unsigned int size, void* ctx)
	{
		rapidjson::Document inDoc;
		inDoc.Parse(args);

		const char* cmd = inDoc["cmd"].GetString();

		if (strcmp(cmd, "LIST") == 0)
		{
			std::string path;
			path += PACKAGE_DIR;
			path += inDoc["path"].GetString();

			rapidjson::Document outDoc;
			rapidjson::Document::AllocatorType& allocator = outDoc.GetAllocator();

			outDoc.SetObject();
			outDoc.AddMember("id", "LIST", allocator);

			outDoc.AddMember("data", khofmann::enumerateDir(path.c_str(), allocator).Move(), allocator);

			rapidjson::StringBuffer strbuf;
			rapidjson::Writer<rapidjson::StringBuffer> writer(strbuf);
			outDoc.Accept(writer);

			fsCommBusCall(DATA, strbuf.GetString(), strbuf.GetSize(), FsCommBusBroadcast_JS);
		}
		else
		{
			rapidjson::Document inDoc;
			inDoc.Parse(args);

			const char* cmd = inDoc["cmd"].GetString();

			if (strcmp(cmd, "LOAD") == 0)
			{
				std::string path;
				path += PACKAGE_DIR; 
				path += inDoc["file"].GetString();

				khofmann::log(stdout, "Loading file %s\n", (void*)path.c_str());

				rapidjson::Document outDoc;
				rapidjson::Document::AllocatorType& allocator = outDoc.GetAllocator();

				outDoc.SetObject();
				outDoc.AddMember("id", "LOAD", allocator);
				outDoc.AddMember("data", khofmann::readFile(path.c_str(), allocator).Move(), allocator);

				rapidjson::StringBuffer strbuf;
				rapidjson::Writer<rapidjson::StringBuffer> writer(strbuf);
				outDoc.Accept(writer);

				fsCommBusCall(DATA, strbuf.GetString(), strbuf.GetSize(), FsCommBusBroadcast_JS);
			}
		}
	}
}
