use core::ffi::c_void;

use windows::Win32::Foundation::{
    CloseHandle,
    HANDLE,
    HINSTANCE,
};
use windows::Win32::System::SystemServices::{
    DLL_PROCESS_ATTACH,
    DLL_PROCESS_DETACH,
    DLL_THREAD_ATTACH,
    DLL_THREAD_DETACH,
};
use windows::Win32::System::Threading::{
    CreateThread,
    THREAD_CREATION_FLAGS,
};
use windows::Win32::UI::WindowsAndMessaging::{
    MB_OK,
    MessageBoxA,
};
use windows_strings::s;

{% for func_name, _ordinal in exported_symbols %}
#[unsafe(no_mangle)]
#[allow(non_snake_case)]
fn {{ func_name }}() {}
{% endfor %}

#[unsafe(no_mangle)]
#[allow(non_snake_case)]
extern "system" fn DllMain(_dll_module: HINSTANCE, dw_reason: u32, _lp_reserved: *mut ()) -> bool {
    match dw_reason {
        DLL_PROCESS_ATTACH => {
            unsafe {
                let t_handle: HANDLE = match CreateThread(
                    None,
                    0,
                    Some(main),
                    None,
                    THREAD_CREATION_FLAGS(0),
                    None,
                ) {
                    Err(_e) => { return false; },
                    Ok(value) => value,
                };

                let _ = CloseHandle(t_handle);
            }
        },
        DLL_PROCESS_DETACH => (),
        DLL_THREAD_ATTACH => (),
        DLL_THREAD_DETACH => (),
        _ => (),
    }

    true
}

extern "system" fn main(_lp_param: *mut c_void) -> u32 {
    unsafe {
        MessageBoxA(None, s!("Hello, world!"), s!("DLL proxy"), MB_OK);
    }

    1
}
