#include <string.h>
 
#include "nrf_log.h"
#include "tstat.h"
 
static const uint8_t TSTATCharName[] = "TSTAT";
 
/**@brief Function for handling the Connect event.
 *
 * @param[in]   p_led_service  LED service structure.
 * @param[in]   p_ble_evt      Event received from the BLE stack.
 */
static void on_connect(ble_tstat_t * p_tstat, ble_evt_t const * p_ble_evt)
{
    p_tstat->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
}
 
/**@brief Function for handling the Disconnect event.
 *
 * @param[in]   p_bas       LED service structure.
 * @param[in]   p_ble_evt   Event received from the BLE stack.
 */
static void on_disconnect(ble_tstat_t * p_tstat, ble_evt_t const * p_ble_evt)
{
    UNUSED_PARAMETER(p_ble_evt);
    p_tstat->conn_handle = BLE_CONN_HANDLE_INVALID;
}
 
/**@brief Function for handling the Write event.
 *
 * @param[in] p_led_service   LED Service structure.
 * @param[in] p_ble_evt       Event received from the BLE stack.
 */
static void on_write(ble_tstat_t * p_tstat, ble_evt_t const * p_ble_evt)
{
    
}
 
/**@brief Function for adding the LED 2 characteristic.
 *
 */
static uint32_t tstat_char_add(ble_tstat_t * p_tstat)
{
    ble_gatts_char_md_t char_md;
    ble_gatts_attr_t    attr_char_value;
    ble_gatts_attr_md_t attr_md;
    ble_uuid_t          ble_uuid;
 
    memset(&char_md, 0, sizeof(char_md));
    memset(&attr_md, 0, sizeof(attr_md));
    memset(&attr_char_value, 0, sizeof(attr_char_value));
 
    char_md.char_props.read          = 1;
    char_md.char_props.notify        = 1;
    char_md.p_char_user_desc         = TSTATCharName;
    char_md.char_user_desc_size      = sizeof(TSTATCharName);
    char_md.char_user_desc_max_size  = sizeof(TSTATCharName);
    char_md.p_char_pf                = NULL;
    char_md.p_user_desc_md           = NULL;
    char_md.p_cccd_md                = NULL;
    char_md.p_sccd_md                = NULL;
 
    // Define the LED 2 Characteristic UUID
    ble_uuid.type = p_tstat->uuid_type;
    ble_uuid.uuid = TZC_TSTAT_CHAR_UUID;
 
    // Set permissions on the Characteristic value
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
 
    // Attribute Metadata settings
    attr_md.vloc       = BLE_GATTS_VLOC_STACK;
    attr_md.rd_auth    = 0;
    attr_md.wr_auth    = 0;
    attr_md.vlen       = 0;
 
    // Attribute Value settings
    attr_char_value.p_uuid       = &ble_uuid;
    attr_char_value.p_attr_md    = &attr_md;
    attr_char_value.init_len     = sizeof(uint8_t);
    attr_char_value.init_offs    = 0;
    attr_char_value.max_len      = sizeof(uint8_t);
    attr_char_value.p_value      = NULL;
 
    return sd_ble_gatts_characteristic_add(p_tstat->service_handle, &char_md,
                                           &attr_char_value,
                                           &p_tstat->tstat_char_handles);
}
 
uint32_t ble_tstat_init(ble_tstat_t * p_tstat, const ble_tstat_init_t * p_tstat_init)
{
    uint32_t   err_code;
    ble_uuid_t ble_uuid;
 
    // Initialize service structure
    p_tstat->conn_handle = BLE_CONN_HANDLE_INVALID;
 
    // Add service UUID
    ble_uuid128_t base_uuid = {TZC_SERVICE_UUID_BASE};
    err_code = sd_ble_uuid_vs_add(&base_uuid, &p_tstat->uuid_type);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
 
    // Set up the UUID for the service (base + service-specific)
    ble_uuid.type = p_tstat->uuid_type;
    ble_uuid.uuid = TZC_SERVICE_UUID;
 
    // Set up and add the service
    err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_tstat->service_handle);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
 
    // Add the different characteristics in the service:
    //   Button press characteristic:   E54B0002-67F5-479E-8711-B3B99198CE6C
    err_code = tstat_char_add(p_tstat);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
 
    return NRF_SUCCESS;
}
 
void ble_tstat_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
{
    ble_tstat_t * p_tstat = (ble_tstat_t *)p_context;
 
    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
            on_connect(p_tstat, p_ble_evt);
            break;
 
        case BLE_GATTS_EVT_WRITE:
            on_write(p_tstat, p_ble_evt);
            break;
 
        case BLE_GAP_EVT_DISCONNECTED:
            on_disconnect(p_tstat, p_ble_evt);
            break;
 
        default:
            // No implementation needed.
            break;
    }
}

uint32_t ble_tstat_on_heat_signal_change(uint16_t conn_handle, ble_tstat_t * p_tstat, uint8_t heatSignal)
{
    ble_gatts_hvx_params_t params;
    uint16_t len = sizeof(heatSignal);

    memset(&params, 0, sizeof(params));
    params.type   = BLE_GATT_HVX_NOTIFICATION;
    params.handle = p_tstat->tstat_char_handles.value_handle;
    params.p_data = &heatSignal;
    params.p_len  = &len;

    return sd_ble_gatts_hvx(conn_handle, &params);
}