use pyo3::prelude::*;

mod client;
mod client_keyboard;
mod client_monitor;
mod client_mouse;
mod client_systemt;

pub mod encryption;
pub mod keys;
pub mod protocol;

// Re-export the main struct for easier access: kmbox_rust::KmBoxNet
pub use client::KmBoxNetClient;
pub use client::KmBoxNetMonitor;

#[pymodule]
fn kmbox_net(m: &Bound<'_, PyModule>) -> PyResult<()> {
    m.add_class::<KmBoxNetClient>()?;
    m.add_class::<KmBoxNetMonitor>()?;
    m.add_class::<protocol::HardMouse>()?;
    m.add_class::<protocol::HardKeyboard>()?;
    m.add_function(wrap_pyfunction!(encryption::py_xxtea_encrypt, m)?)?;

    // Common Keys
    m.add("KEY_A", keys::KEY_A)?;
    m.add("KEY_B", keys::KEY_B)?;
    m.add("KEY_C", keys::KEY_C)?;
    m.add("KEY_D", keys::KEY_D)?;
    m.add("KEY_E", keys::KEY_E)?;
    m.add("KEY_F", keys::KEY_F)?;
    m.add("KEY_G", keys::KEY_G)?;
    m.add("KEY_H", keys::KEY_H)?;
    m.add("KEY_I", keys::KEY_I)?;
    m.add("KEY_J", keys::KEY_J)?;
    m.add("KEY_K", keys::KEY_K)?;
    m.add("KEY_L", keys::KEY_L)?;
    m.add("KEY_M", keys::KEY_M)?;
    m.add("KEY_N", keys::KEY_N)?;
    m.add("KEY_O", keys::KEY_O)?;
    m.add("KEY_P", keys::KEY_P)?;
    m.add("KEY_Q", keys::KEY_Q)?;
    m.add("KEY_R", keys::KEY_R)?;
    m.add("KEY_S", keys::KEY_S)?;
    m.add("KEY_T", keys::KEY_T)?;
    m.add("KEY_U", keys::KEY_U)?;
    m.add("KEY_V", keys::KEY_V)?;
    m.add("KEY_W", keys::KEY_W)?;
    m.add("KEY_X", keys::KEY_X)?;
    m.add("KEY_Y", keys::KEY_Y)?;
    m.add("KEY_Z", keys::KEY_Z)?;

    m.add("KEY_1", keys::KEY_1_EXCLAMATION_MARK)?;
    m.add("KEY_2", keys::KEY_2_AT)?;
    m.add("KEY_3", keys::KEY_3_NUMBER_SIGN)?;
    m.add("KEY_4", keys::KEY_4_DOLLAR)?;
    m.add("KEY_5", keys::KEY_5_PERCENT)?;
    m.add("KEY_6", keys::KEY_6_CARET)?;
    m.add("KEY_7", keys::KEY_7_AMPERSAND)?;
    m.add("KEY_8", keys::KEY_8_ASTERISK)?;
    m.add("KEY_9", keys::KEY_9_OPARENTHESIS)?;
    m.add("KEY_0", keys::KEY_0_CPARENTHESIS)?;

    m.add("KEY_ENTER", keys::KEY_ENTER)?;
    m.add("KEY_ESCAPE", keys::KEY_ESCAPE)?;
    m.add("KEY_BACKSPACE", keys::KEY_BACKSPACE)?;
    m.add("KEY_TAB", keys::KEY_TAB)?;
    m.add("KEY_SPACEBAR", keys::KEY_SPACEBAR)?;
    m.add("KEY_CAPS_LOCK", keys::KEY_CAPS_LOCK)?;

    m.add("KEY_F1", keys::KEY_F1)?;
    m.add("KEY_F2", keys::KEY_F2)?;
    m.add("KEY_F3", keys::KEY_F3)?;
    m.add("KEY_F4", keys::KEY_F4)?;
    m.add("KEY_F5", keys::KEY_F5)?;
    m.add("KEY_F6", keys::KEY_F6)?;
    m.add("KEY_F7", keys::KEY_F7)?;
    m.add("KEY_F8", keys::KEY_F8)?;
    m.add("KEY_F9", keys::KEY_F9)?;
    m.add("KEY_F10", keys::KEY_F10)?;
    m.add("KEY_F11", keys::KEY_F11)?;
    m.add("KEY_F12", keys::KEY_F12)?;

    m.add("KEY_LEFTCONTROL", keys::KEY_LEFTCONTROL)?;
    m.add("KEY_LEFTSHIFT", keys::KEY_LEFTSHIFT)?;
    m.add("KEY_LEFTALT", keys::KEY_LEFTALT)?;
    m.add("KEY_LEFT_GUI", keys::KEY_LEFT_GUI)?;
    m.add("KEY_RIGHTCONTROL", keys::KEY_RIGHTCONTROL)?;
    m.add("KEY_RIGHTSHIFT", keys::KEY_RIGHTSHIFT)?;
    m.add("KEY_RIGHTALT", keys::KEY_RIGHTALT)?;
    m.add("KEY_RIGHT_GUI", keys::KEY_RIGHT_GUI)?;


    m.add("KEY_NONE", keys::KEY_NONE)?;
    m.add("KEY_ERRORROLLOVER", keys::KEY_ERRORROLLOVER)?;
    m.add("KEY_POSTFAIL", keys::KEY_POSTFAIL)?;
    m.add("KEY_ERRORUNDEFINED", keys::KEY_ERRORUNDEFINED)?;
    m.add("KEY_1_EXCLAMATION_MARK", keys::KEY_1_EXCLAMATION_MARK)?;
    m.add("KEY_2_AT", keys::KEY_2_AT)?;
    m.add("KEY_3_NUMBER_SIGN", keys::KEY_3_NUMBER_SIGN)?;
    m.add("KEY_4_DOLLAR", keys::KEY_4_DOLLAR)?;
    m.add("KEY_5_PERCENT", keys::KEY_5_PERCENT)?;
    m.add("KEY_6_CARET", keys::KEY_6_CARET)?;
    m.add("KEY_7_AMPERSAND", keys::KEY_7_AMPERSAND)?;
    m.add("KEY_8_ASTERISK", keys::KEY_8_ASTERISK)?;
    m.add("KEY_9_OPARENTHESIS", keys::KEY_9_OPARENTHESIS)?;
    m.add("KEY_0_CPARENTHESIS", keys::KEY_0_CPARENTHESIS)?;
    m.add("KEY_MINUS_UNDERSCORE", keys::KEY_MINUS_UNDERSCORE)?;
    m.add("KEY_EQUAL_PLUS", keys::KEY_EQUAL_PLUS)?;
    m.add("KEY_OBRACKET_AND_OBRACE", keys::KEY_OBRACKET_AND_OBRACE)?;
    m.add("KEY_CBRACKET_AND_CBRACE", keys::KEY_CBRACKET_AND_CBRACE)?;
    m.add("KEY_BACKSLASH_VERTICAL_BAR", keys::KEY_BACKSLASH_VERTICAL_BAR)?;
    m.add("KEY_NONUS_NUMBER_SIGN_TILDE", keys::KEY_NONUS_NUMBER_SIGN_TILDE)?;
    m.add("KEY_SEMICOLON_COLON", keys::KEY_SEMICOLON_COLON)?;
    m.add("KEY_SINGLE_AND_DOUBLE_QUOTE", keys::KEY_SINGLE_AND_DOUBLE_QUOTE)?;
    m.add("KEY_GRAVE_ACCENT_AND_TILDE", keys::KEY_GRAVE_ACCENT_AND_TILDE)?;
    m.add("KEY_COMMA_AND_LESS", keys::KEY_COMMA_AND_LESS)?;
    m.add("KEY_DOT_GREATER", keys::KEY_DOT_GREATER)?;
    m.add("KEY_SLASH_QUESTION", keys::KEY_SLASH_QUESTION)?;
    m.add("KEY_PRINTSCREEN", keys::KEY_PRINTSCREEN)?;
    m.add("KEY_SCROLL_LOCK", keys::KEY_SCROLL_LOCK)?;
    m.add("KEY_PAUSE", keys::KEY_PAUSE)?;
    m.add("KEY_INSERT", keys::KEY_INSERT)?;
    m.add("KEY_HOME", keys::KEY_HOME)?;
    m.add("KEY_PAGEUP", keys::KEY_PAGEUP)?;
    m.add("KEY_DELETE", keys::KEY_DELETE)?;
    m.add("KEY_END1", keys::KEY_END1)?;
    m.add("KEY_PAGEDOWN", keys::KEY_PAGEDOWN)?;
    m.add("KEY_RIGHTARROW", keys::KEY_RIGHTARROW)?;
    m.add("KEY_LEFTARROW", keys::KEY_LEFTARROW)?;
    m.add("KEY_DOWNARROW", keys::KEY_DOWNARROW)?;
    m.add("KEY_UPARROW", keys::KEY_UPARROW)?;
    m.add("KEY_KEYPAD_NUM_LOCK_AND_CLEAR", keys::KEY_KEYPAD_NUM_LOCK_AND_CLEAR)?;
    m.add("KEY_KEYPAD_SLASH", keys::KEY_KEYPAD_SLASH)?;
    m.add("KEY_KEYPAD_ASTERIKS", keys::KEY_KEYPAD_ASTERIKS)?;
    m.add("KEY_KEYPAD_MINUS", keys::KEY_KEYPAD_MINUS)?;
    m.add("KEY_KEYPAD_PLUS", keys::KEY_KEYPAD_PLUS)?;
    m.add("KEY_KEYPAD_ENTER", keys::KEY_KEYPAD_ENTER)?;
    m.add("KEY_KEYPAD_1_END", keys::KEY_KEYPAD_1_END)?;
    m.add("KEY_KEYPAD_2_DOWN_ARROW", keys::KEY_KEYPAD_2_DOWN_ARROW)?;
    m.add("KEY_KEYPAD_3_PAGEDN", keys::KEY_KEYPAD_3_PAGEDN)?;
    m.add("KEY_KEYPAD_4_LEFT_ARROW", keys::KEY_KEYPAD_4_LEFT_ARROW)?;
    m.add("KEY_KEYPAD_5", keys::KEY_KEYPAD_5)?;
    m.add("KEY_KEYPAD_6_RIGHT_ARROW", keys::KEY_KEYPAD_6_RIGHT_ARROW)?;
    m.add("KEY_KEYPAD_7_HOME", keys::KEY_KEYPAD_7_HOME)?;
    m.add("KEY_KEYPAD_8_UP_ARROW", keys::KEY_KEYPAD_8_UP_ARROW)?;
    m.add("KEY_KEYPAD_9_PAGEUP", keys::KEY_KEYPAD_9_PAGEUP)?;
    m.add("KEY_KEYPAD_0_INSERT", keys::KEY_KEYPAD_0_INSERT)?;
    m.add("KEY_KEYPAD_DECIMAL_SEPARATOR_DELETE", keys::KEY_KEYPAD_DECIMAL_SEPARATOR_DELETE)?;
    m.add("KEY_NONUS_BACK_SLASH_VERTICAL_BAR", keys::KEY_NONUS_BACK_SLASH_VERTICAL_BAR)?;
    m.add("KEY_APPLICATION", keys::KEY_APPLICATION)?;
    m.add("KEY_POWER", keys::KEY_POWER)?;
    m.add("KEY_KEYPAD_EQUAL", keys::KEY_KEYPAD_EQUAL)?;
    m.add("KEY_F13", keys::KEY_F13)?;
    m.add("KEY_F14", keys::KEY_F14)?;
    m.add("KEY_F15", keys::KEY_F15)?;
    m.add("KEY_F16", keys::KEY_F16)?;
    m.add("KEY_F17", keys::KEY_F17)?;
    m.add("KEY_F18", keys::KEY_F18)?;
    m.add("KEY_F19", keys::KEY_F19)?;
    m.add("KEY_F20", keys::KEY_F20)?;
    m.add("KEY_F21", keys::KEY_F21)?;
    m.add("KEY_F22", keys::KEY_F22)?;
    m.add("KEY_F23", keys::KEY_F23)?;
    m.add("KEY_F24", keys::KEY_F24)?;
    m.add("KEY_EXECUTE", keys::KEY_EXECUTE)?;
    m.add("KEY_HELP", keys::KEY_HELP)?;
    m.add("KEY_MENU", keys::KEY_MENU)?;
    m.add("KEY_SELECT", keys::KEY_SELECT)?;
    m.add("KEY_STOP", keys::KEY_STOP)?;
    m.add("KEY_AGAIN", keys::KEY_AGAIN)?;
    m.add("KEY_UNDO", keys::KEY_UNDO)?;
    m.add("KEY_CUT", keys::KEY_CUT)?;
    m.add("KEY_COPY", keys::KEY_COPY)?;
    m.add("KEY_PASTE", keys::KEY_PASTE)?;
    m.add("KEY_FIND", keys::KEY_FIND)?;
    m.add("KEY_MUTE", keys::KEY_MUTE)?;
    m.add("KEY_VOLUME_UP", keys::KEY_VOLUME_UP)?;
    m.add("KEY_VOLUME_DOWN", keys::KEY_VOLUME_DOWN)?;
    m.add("KEY_LOCKING_CAPS_LOCK", keys::KEY_LOCKING_CAPS_LOCK)?;
    m.add("KEY_LOCKING_NUM_LOCK", keys::KEY_LOCKING_NUM_LOCK)?;
    m.add("KEY_LOCKING_SCROLL_LOCK", keys::KEY_LOCKING_SCROLL_LOCK)?;
    m.add("KEY_KEYPAD_COMMA", keys::KEY_KEYPAD_COMMA)?;
    m.add("KEY_KEYPAD_EQUAL_SIGN", keys::KEY_KEYPAD_EQUAL_SIGN)?;
    m.add("KEY_INTERNATIONAL1", keys::KEY_INTERNATIONAL1)?;
    m.add("KEY_INTERNATIONAL2", keys::KEY_INTERNATIONAL2)?;
    m.add("KEY_INTERNATIONAL3", keys::KEY_INTERNATIONAL3)?;
    m.add("KEY_INTERNATIONAL4", keys::KEY_INTERNATIONAL4)?;
    m.add("KEY_INTERNATIONAL5", keys::KEY_INTERNATIONAL5)?;
    m.add("KEY_INTERNATIONAL6", keys::KEY_INTERNATIONAL6)?;
    m.add("KEY_INTERNATIONAL7", keys::KEY_INTERNATIONAL7)?;
    m.add("KEY_INTERNATIONAL8", keys::KEY_INTERNATIONAL8)?;
    m.add("KEY_INTERNATIONAL9", keys::KEY_INTERNATIONAL9)?;
    m.add("KEY_LANG1", keys::KEY_LANG1)?;
    m.add("KEY_LANG2", keys::KEY_LANG2)?;
    m.add("KEY_LANG3", keys::KEY_LANG3)?;
    m.add("KEY_LANG4", keys::KEY_LANG4)?;
    m.add("KEY_LANG5", keys::KEY_LANG5)?;
    m.add("KEY_LANG6", keys::KEY_LANG6)?;
    m.add("KEY_LANG7", keys::KEY_LANG7)?;
    m.add("KEY_LANG8", keys::KEY_LANG8)?;
    m.add("KEY_LANG9", keys::KEY_LANG9)?;
    m.add("KEY_ALTERNATE_ERASE", keys::KEY_ALTERNATE_ERASE)?;
    m.add("KEY_SYSREQ", keys::KEY_SYSREQ)?;
    m.add("KEY_CANCEL", keys::KEY_CANCEL)?;
    m.add("KEY_CLEAR", keys::KEY_CLEAR)?;
    m.add("KEY_PRIOR", keys::KEY_PRIOR)?;
    m.add("KEY_RETURN", keys::KEY_RETURN)?;
    m.add("KEY_SEPARATOR", keys::KEY_SEPARATOR)?;
    m.add("KEY_OUT", keys::KEY_OUT)?;
    m.add("KEY_OPER", keys::KEY_OPER)?;
    m.add("KEY_CLEAR_AGAIN", keys::KEY_CLEAR_AGAIN)?;
    m.add("KEY_CRSEL", keys::KEY_CRSEL)?;
    m.add("KEY_EXSEL", keys::KEY_EXSEL)?;
    m.add("KEY_KEYPAD_00", keys::KEY_KEYPAD_00)?;
    m.add("KEY_KEYPAD_000", keys::KEY_KEYPAD_000)?;
    m.add("KEY_THOUSANDS_SEPARATOR", keys::KEY_THOUSANDS_SEPARATOR)?;
    m.add("KEY_DECIMAL_SEPARATOR", keys::KEY_DECIMAL_SEPARATOR)?;
    m.add("KEY_CURRENCY_UNIT", keys::KEY_CURRENCY_UNIT)?;
    m.add("KEY_CURRENCY_SUB_UNIT", keys::KEY_CURRENCY_SUB_UNIT)?;
    m.add("KEY_KEYPAD_OPARENTHESIS", keys::KEY_KEYPAD_OPARENTHESIS)?;
    m.add("KEY_KEYPAD_CPARENTHESIS", keys::KEY_KEYPAD_CPARENTHESIS)?;
    m.add("KEY_KEYPAD_OBRACE", keys::KEY_KEYPAD_OBRACE)?;
    m.add("KEY_KEYPAD_CBRACE", keys::KEY_KEYPAD_CBRACE)?;
    m.add("KEY_KEYPAD_TAB", keys::KEY_KEYPAD_TAB)?;
    m.add("KEY_KEYPAD_BACKSPACE", keys::KEY_KEYPAD_BACKSPACE)?;
    m.add("KEY_KEYPAD_A", keys::KEY_KEYPAD_A)?;
    m.add("KEY_KEYPAD_B", keys::KEY_KEYPAD_B)?;
    m.add("KEY_KEYPAD_C", keys::KEY_KEYPAD_C)?;
    m.add("KEY_KEYPAD_D", keys::KEY_KEYPAD_D)?;
    m.add("KEY_KEYPAD_E", keys::KEY_KEYPAD_E)?;
    m.add("KEY_KEYPAD_F", keys::KEY_KEYPAD_F)?;
    m.add("KEY_KEYPAD_XOR", keys::KEY_KEYPAD_XOR)?;
    m.add("KEY_KEYPAD_CARET", keys::KEY_KEYPAD_CARET)?;
    m.add("KEY_KEYPAD_PERCENT", keys::KEY_KEYPAD_PERCENT)?;
    m.add("KEY_KEYPAD_LESS", keys::KEY_KEYPAD_LESS)?;
    m.add("KEY_KEYPAD_GREATER", keys::KEY_KEYPAD_GREATER)?;
    m.add("KEY_KEYPAD_AMPERSAND", keys::KEY_KEYPAD_AMPERSAND)?;
    m.add("KEY_KEYPAD_LOGICAL_AND", keys::KEY_KEYPAD_LOGICAL_AND)?;
    m.add("KEY_KEYPAD_VERTICAL_BAR", keys::KEY_KEYPAD_VERTICAL_BAR)?;
    m.add("KEY_KEYPAD_LOGIACL_OR", keys::KEY_KEYPAD_LOGIACL_OR)?;
    m.add("KEY_KEYPAD_COLON", keys::KEY_KEYPAD_COLON)?;
    m.add("KEY_KEYPAD_NUMBER_SIGN", keys::KEY_KEYPAD_NUMBER_SIGN)?;
    m.add("KEY_KEYPAD_SPACE", keys::KEY_KEYPAD_SPACE)?;
    m.add("KEY_KEYPAD_AT", keys::KEY_KEYPAD_AT)?;
    m.add("KEY_KEYPAD_EXCLAMATION_MARK", keys::KEY_KEYPAD_EXCLAMATION_MARK)?;
    m.add("KEY_KEYPAD_MEMORY_STORE", keys::KEY_KEYPAD_MEMORY_STORE)?;
    m.add("KEY_KEYPAD_MEMORY_RECALL", keys::KEY_KEYPAD_MEMORY_RECALL)?;
    m.add("KEY_KEYPAD_MEMORY_CLEAR", keys::KEY_KEYPAD_MEMORY_CLEAR)?;
    m.add("KEY_KEYPAD_MEMORY_ADD", keys::KEY_KEYPAD_MEMORY_ADD)?;
    m.add("KEY_KEYPAD_MEMORY_SUBTRACT", keys::KEY_KEYPAD_MEMORY_SUBTRACT)?;
    m.add("KEY_KEYPAD_MEMORY_MULTIPLY", keys::KEY_KEYPAD_MEMORY_MULTIPLY)?;
    m.add("KEY_KEYPAD_MEMORY_DIVIDE", keys::KEY_KEYPAD_MEMORY_DIVIDE)?;
    m.add("KEY_KEYPAD_PLUSMINUS", keys::KEY_KEYPAD_PLUSMINUS)?;
    m.add("KEY_KEYPAD_CLEAR", keys::KEY_KEYPAD_CLEAR)?;
    m.add("KEY_KEYPAD_CLEAR_ENTRY", keys::KEY_KEYPAD_CLEAR_ENTRY)?;
    m.add("KEY_KEYPAD_BINARY", keys::KEY_KEYPAD_BINARY)?;
    m.add("KEY_KEYPAD_OCTAL", keys::KEY_KEYPAD_OCTAL)?;
    m.add("KEY_KEYPAD_DECIMAL", keys::KEY_KEYPAD_DECIMAL)?;
    m.add("KEY_KEYPAD_HEXADECIMAL", keys::KEY_KEYPAD_HEXADECIMAL)?;

    Ok(())
}
