/**************************************************************************/
/*  aethex_vm.h                                                           */
/**************************************************************************/
/*                         This file is part of:                          */
/*                          AETHEX ENGINE                                 */
/*                     https://aethex.foundation                          */
/**************************************************************************/
/* Copyright (c) 2026-present AeThex Labs.                                */
/**************************************************************************/

#ifndef AETHEX_VM_H
#define AETHEX_VM_H

#include "aethex_compiler.h"
#include "core/object/ref_counted.h"
#include "core/variant/variant.h"

// ==========================================
// AeThex Virtual Machine
// ==========================================
// Executes compiled AeThex bytecode
// Stack-based VM with support for:
// - Cross-platform sync operations
// - Beacon (signal) emission
// - Async/await patterns
// ==========================================

class AeThexVM : public RefCounted {
	GDCLASS(AeThexVM, RefCounted);

public:
	enum InterpretResult {
		INTERPRET_OK,
		INTERPRET_COMPILE_ERROR,
		INTERPRET_RUNTIME_ERROR,
	};

	struct CallFrame {
		const AeThexCompiler::Chunk *chunk = nullptr;
		int ip = 0;
		int stack_base = 0;
		String function_name;
	};

private:
	static const int STACK_MAX = 256;
	static const int FRAMES_MAX = 64;
	
	Variant stack[STACK_MAX];
	int stack_top = 0;
	
	CallFrame frames[FRAMES_MAX];
	int frame_count = 0;
	
	HashMap<String, Variant> globals;
	HashMap<String, Callable> native_functions;
	
	const AeThexCompiler::CompiledScript *script = nullptr;
	String runtime_error;
	bool debug_trace = false;
	
	// Execution
	InterpretResult run();
	
	// Stack operations
	void push(const Variant &value);
	Variant pop();
	Variant peek(int distance = 0) const;
	void reset_stack();
	
	// Frame operations
	bool call_function(const String &name, int arg_count);
	bool call_native(const String &name, int arg_count);
	
	// Bytecode reading
	uint8_t read_byte();
	uint16_t read_short();
	int32_t read_int();
	float read_float();
	const String &read_string();
	Variant read_constant();
	
	// Native function registration
	void register_builtin_functions();
	
	// Error handling
	void runtime_error_at(const String &message);

protected:
	static void _bind_methods();

public:
	AeThexVM();
	~AeThexVM();
	
	// Execute compiled script
	InterpretResult execute(const AeThexCompiler::CompiledScript *p_script);
	
	// Call a specific function
	InterpretResult call(const String &function_name, const Vector<Variant> &args = Vector<Variant>());
	
	// Global variables
	void set_global(const String &name, const Variant &value);
	Variant get_global(const String &name) const;
	bool has_global(const String &name) const;
	
	// Native function binding
	void register_native_function(const String &name, const Callable &callable);
	
	// Error info
	String get_error() const { return runtime_error; }
	bool has_error() const { return !runtime_error.is_empty(); }
	
	// Debug
	void set_debug_trace(bool p_trace) { debug_trace = p_trace; }
	void print_stack() const;
	void disassemble_chunk(const AeThexCompiler::Chunk &chunk, const String &name) const;
};

VARIANT_ENUM_CAST(AeThexVM::InterpretResult);

#endif // AETHEX_VM_H
