#include "node.h"
#include "v8.h"
#include <iostream>
#include <vector>
#include <memory>
#include <cstdint>
#include <cstring>

using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Context;
using v8::Local;
using v8::NewStringType;
using v8::Object;
using v8::String;
using v8::Value;
using v8::ArrayBuffer;
using v8::Exception;
using v8::Number;
using v8::Uint32;
using v8::Uint8Array;
using v8::Persistent;

#ifdef _WIN32
#include "windows.h"
#include <direct.h>

#define getProccessAddress GetProcAddress
HINSTANCE HypertubeNodejsRuntimeNativeLibInstance{ nullptr };
#endif	// _WIN32

#if defined(__linux__) || defined(__APPLE__)
#include <dlfcn.h>
#include <unistd.h>
#include <limits.h>
#define getProccessAddress dlsym
void* HypertubeNodejsRuntimeNativeLibInstance{ nullptr };
#endif	// __linux__ || __APPLE__


using byte = uint8_t;

std::string nativeLibFullPath{ "" };

Isolate* isolate = nullptr;
Persistent<v8::Context> permanentContext; // permanent context
v8::Persistent<v8::Object> receiverNative; // permanent receiver object

typedef std::vector<byte>(*nodejsCallback)(byte* messageByteArray, int32_t messageByteArrayLen); // type of the callback function

typedef int(*SendCommandNative)(byte*, int);
typedef int(*ReadResponseNative)(byte*, int);
typedef int(*ActivateNative)(const char*);
typedef const char*(*GetNativeErrorNative)();
typedef int(*SetConfigSourceNative)(const char*);
typedef int(*SetWorkingDirectoryNative)(const char*);
typedef bool(*SetCallbackNative)(nodejsCallback); // type of the function to pass callback to the native library

SendCommandNative SendCommandNative_Fn{ nullptr };
ReadResponseNative ReadResponseNative_Fn{ nullptr };
ActivateNative ActivateNative_Fn{ nullptr };
GetNativeErrorNative GetNativeErrorNative_Fn{ nullptr };
SetConfigSourceNative SetConfigSourceNative_Fn{ nullptr };
SetWorkingDirectoryNative SetWorkingDirectoryNative_Fn{ nullptr };
SetCallbackNative SetCallbackNative_Fn{ nullptr }; // function to pass callback to the native library

std::vector<byte> nodejsRuntimeCallback(byte* messageByteArray, int32_t messageByteArrayLen); // callback function to be passed to the native library
