#ifndef BLE_TEST_H__
#define BLE_TEST_H__

#include <stdint.h>
#include <stdbool.h>
#include "sdk_config.h"
#include "ble.h"
#include "ble_srv_common.h"
#include "nrf_sdh_ble.h"
#include "ble_link_ctx_manager.h"

#ifdef __cplusplus
extern "C" {
#endif

/**@brief   Macro for defining a ble_nus instance.
 *
 * @param     _name            Name of the instance.
 * @param[in] _test_max_clients Maximum number of TEST clients connected at a time.
 * @hideinitializer
 */
#define BLE_TEST_DEF(_name, _test_max_clients)                      \
    BLE_LINK_CTX_MANAGER_DEF(CONCAT_2(_name, _link_ctx_storage),  \
                             (_test_max_clients),                  \
                             sizeof(ble_test_client_context_t));   \
    static ble_test_t _name =                                      \
    {                                                             \
        .p_link_ctx_storage = &CONCAT_2(_name, _link_ctx_storage) \
    };                                                            \
    NRF_SDH_BLE_OBSERVER(_name ## _obs,                           \
                         BLE_NUS_BLE_OBSERVER_PRIO,               \
                         ble_test_on_ble_evt,                      \
                         &_name)

#define BLE_UUID_TEST_SERVICE 0x0001 /**< The UUID of the TEST Service. */

/**@brief   TEST Service event types. */
typedef enum
{
    BLE_TEST_EVT_RX_NAME,      													/**< new name received. */
    BLE_TEST_EVT_COMM_STARTED, 													/**< Notification has been enabled. */
    BLE_TEST_EVT_COMM_STOPPED,													/**< Notification has been disabled. */
} ble_test_evt_type_t;

typedef struct ble_test_s ble_test_t;

///**@brief TEST Service client context structure.
// *
// * @details This structure contains state context related to hosts.
// */
typedef struct
{
    bool is_notification_enabled; /**< Variable to indicate if the peer has enabled notification of the RX characteristic.*/
} ble_test_client_context_t;


/**@brief   TEST Service event structure.
 *
 * @details This structure is passed to an event coming from service.
 */
typedef struct
{
    ble_test_evt_type_t         type;        /**< Event type. */
    ble_test_t                * p_testService;       /**< A pointer to the instance. */
    uint16_t                   conn_handle; /**< Connection handle. */
    ble_test_client_context_t * p_link_ctx;  /**< A pointer to the link context. */
	uint8_t const * p_data; /**< A pointer to the buffer with received data. */
	uint16_t        length; /**< Length of received data. */
} ble_test_evt_t;


/**@brief TEST Service event handler type. */
typedef void (* ble_test_data_handler_t) (ble_test_evt_t * p_evt);


/**@brief   TEST Service initialization structure.
 *
 * @details This structure contains the initialization information for the service. The application
 * must fill this structure and pass it to the service using the @ref ble_nus_init
 *          function.
 */
typedef struct
{
    ble_test_data_handler_t data_handler; /**< Event handler to be called for handling received data. */
} ble_test_init_t;


/**@brief   TEST Service structure.
 *
 * @details This structure contains status information related to the service.
 */
struct ble_test_s
{
    uint8_t                         uuid_type;          		/**< UUID type for Service Base UUID. */
    uint16_t                        service_handle;     		/**< Handle of Service (as provided by the SoftDevice). */
    ble_gatts_char_handles_t        name_handles;       		/**< Handles related to the name characteristic (as provided by the SoftDevice). */
    blcm_link_ctx_storage_t * const p_link_ctx_storage; 		/**< Pointer to link context storage with handles of all current connections and its context. */
    ble_test_data_handler_t       data_handler;       		/**< Event handler to be called for handling received data. */
};

uint32_t ble_test_init(ble_test_t * p_test, ble_test_init_t const * p_test_init);


void ble_test_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);


/**
* @brief   Function for updating the name.
 */
uint32_t UpdateTestName(ble_test_t * p_test, uint16_t conn_handle, uint8_t *pData, uint16_t length);


#ifdef __cplusplus
}
#endif

#endif // BLE_TEST_H__

/** @} */
