extern "C" {
    fn __k3_sxt_execute_raw(sql_ptr: u32) -> u32;
    fn __k3_sxt_execute_create_table(table_name_ptr: u32, table_types_ptr: u32) -> u32;
}

pub fn execute_sql(sql: &str) -> String {
    let mut sql_buf = (sql.len() as u32).to_le_bytes().to_vec();
    sql_buf.extend_from_slice(sql.as_bytes());
    let res_ptr = unsafe { __k3_sxt_execute_raw(sql_buf.as_ptr() as u32) } as *mut u8;
    let len = u32::from_le_bytes(
        unsafe { std::slice::from_raw_parts(res_ptr, 4) }
            .try_into()
            .unwrap(),
    );
    let mut res = vec![0u8; len as usize];
    res.copy_from_slice(unsafe { std::slice::from_raw_parts(res_ptr.add(4), len as usize) });
    String::from_utf8(res).unwrap()
}

pub fn execute_create_table(name: &str, types: &str) -> String {
    let mut name_buf = (name.len() as u32).to_le_bytes().to_vec();
    name_buf.extend_from_slice(name.as_bytes());
    let mut types_buf = (types.len() as u32).to_le_bytes().to_vec();
    types_buf.extend_from_slice(types.as_bytes());

    let res_ptr = unsafe {
        __k3_sxt_execute_create_table(name_buf.as_ptr() as u32, types_buf.as_ptr() as u32)
    } as *mut u8;
    let len = u32::from_le_bytes(
        unsafe { std::slice::from_raw_parts(res_ptr, 4) }
            .try_into()
            .unwrap(),
    );
    let mut res = vec![0u8; len as usize];
    res.copy_from_slice(unsafe { std::slice::from_raw_parts(res_ptr.add(4), len as usize) });
    String::from_utf8(res).unwrap()
}
