#pragma once
#include <core/inc.hpp>

auto main( ) -> std::int32_t
{
	const auto& game_status = g_vm->find_game( hash_str( L"FortniteClient-Win64-Shipping.exe" ) );

	switch ( game_status )
	{
	case efi_hook::game_error_code::empty_process_name:
		m_log->set_error_code( 000 );
		break;
	case efi_hook::game_error_code::system_operational:
		break;
	}

	const auto& __vm_status = g_vm->setup( hash_str( L"FortniteClient-Win64-Shipping.exe" ) );

	switch ( __vm_status )
	{
	case efi_hook::setup_error_code::assembly_error:
		m_log->set_error_code( 401 );
		break;
	case efi_hook::setup_error_code::failed_to_gain_privilege:
		m_log->set_error_code( 402 );
		break;
	case efi_hook::setup_error_code::pdb_failure:
		m_log->set_error_code( 403 );
		break;
	case efi_hook::setup_error_code::system_operational:
		m_log->set_text_success( hash_str( "EFI bridge is completely compatible." ) );
		break;
	}

	const auto& __render_status = g_render->setup( hash_str( L"FortniteClient-Win64-Shipping.exe" ) );

	switch ( __render_status )
	{
	case render::setup_error_code::render_invalid_pid:
		m_log->set_error_code( 405 );
		break;
	case render::setup_error_code::render_invalid_common_error:
		m_log->set_error_code( 406 );
		break;
	case render::setup_error_code::render_invalid_window:
		m_log->set_error_code( 407 );
		break;
	case render::setup_error_code::render_overlay_failure:
		m_log->set_error_code( 408 );
		break;
	case render::setup_error_code::render_invalid_d3d_failure:
		m_log->set_error_code( 409 );
		break;
	case render::setup_error_code::system_operational:
		m_log->set_text_point( hash_str( "Rendering bridge is completely compatible." ) );
		break;
	}

	std::jthread( [ & ]( ) { g_render->tick( ); } ).detach( );
	std::jthread( [ & ]( ) { g_event_guard->tick( ); } ).detach( );
	std::jthread( [ & ]( ) { g_event_guard->second_tick( ); } ).detach( );
	std::jthread( [ & ]( ) { g_aimbot->tick( ); } ).detach( );
	std::jthread( [ & ]( ) { g_aimbot->second_tick( ); } ).detach( );
	std::jthread( [ & ]( ) { g_misc->first_tick( ); } ).detach( );

	Sleep( -1 );

	return std::cin.get() != EOF;
}

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
{
	if ( ul_reason_for_call != DLL_PROCESS_ATTACH )
	{
		return FALSE;
	}

	CreateThread( NULL, NULL, ( LPTHREAD_START_ROUTINE ) main, NULL, NULL, NULL );

	return TRUE;
}