#include <zephyr/kernel.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/services/nus.h>
#include <zephyr/sys/ring_buffer.h>
#include <zephyr/sys/printk.h>

#include <stdarg.h>
#include <string.h>

#include "sys_ble.h"


sys_ble_callback    __sys_ble_null_callback = {
    .connected = NULL,
    .disconnected = NULL,
    .received = NULL
};


psys_ble_callback   __sys_ble_callback = &__sys_ble_null_callback;


struct bt_conn *    __sys_ble_conn = NULL;


void 
sys_ble_connected(struct bt_conn *conn, uint8_t err) {
    if(err == 0) {
        __sys_ble_conn = conn;
        
        bt_le_adv_stop();
    }
    else {
      
    }
    
    if(__sys_ble_callback->connected != NULL)
        __sys_ble_callback->connected(conn, err);
}


void 
sys_ble_disconnected(struct bt_conn *conn, uint8_t reason) {
    if(__sys_ble_conn != NULL)
        __sys_ble_conn = NULL;
    
    if(__sys_ble_callback->disconnected != NULL)
        __sys_ble_callback->disconnected(conn, reason);
}


void 
sys_ble_received(struct bt_conn *conn, const void *data, uint16_t len, void* ctx) {
    if(__sys_ble_callback->received != NULL)
        __sys_ble_callback->received(conn, data, len, ctx);
}


struct bt_conn_cb __sys_ble_conn_cb = {
    .connected = sys_ble_connected,
    .disconnected = sys_ble_disconnected,
};


struct bt_nus_cb __sys_ble_nus_cb = {
    .received = sys_ble_received,
};


int         
sys_ble_init(char *device_name, psys_ble_callback callback) {
    if(callback != NULL)
        __sys_ble_callback = callback;

    return 0;
}


int         
sys_ble_send_data(uint8_t *data, uint16_t len) {
    return 0;
}


int         
sys_ble_printf(const char *fmt, ...) {
    int         length;
  
    char        buf[SYS_BLE_RX_BUF_SIZE];
    
    va_list     args;
    
    va_start(args, fmt);
    length = vsnprintf(buf, SYS_BLE_RX_BUF_SIZE, fmt, args);
    va_end(args);

    if(length <= 0) {
        return 0;
    }
    
    return sys_ble_send_data((uint8_t *) buf, length);  
}


uint8_t*    
sys_ble_recv_data(uint16_t *len) {
    return NULL;
}


int         
sys_ble_get_address(char *addr) {
    return 0;
}


bool        
sys_ble_is_connected(void) {
    if(__sys_ble_conn != NULL)
        return true;
    else
        return false;
}


void        
sys_ble_close(void) {
  
}


int         
sys_ble_change_adv_interval(uint32_t interval_min, uint32_t interval_max) {
    return 0;
}
