#include "sdk_config.h"
#include "battery_ble.h"
#include "ble_bas.h"
#include "battery_voltage.h"
#include "ble_srv_common.h"
#include "error.h"
#include "nrf_log.h"

#define INVALID_BATTERY_LEVEL 0xFF // Invalid/default battery level.

static bool      _gBleBasInitialized = false;
static ble_bas_t _gBleBas;

/* Event handler, handles events in the Battery Service.
 *
 * details This callback function is often used to enable a service when requested over BLE,
 * and disable when not requested to save power. m_batt_meas runs all the time, so no
 * enabling/disabling is performed.
 */
static void _batteryBleEvtHandler(ble_bas_t * pBas, ble_bas_evt_t * pEvt)
{
    switch (pEvt->evt_type)
    {
        case BLE_BAS_EVT_NOTIFICATION_ENABLED:
            NRF_LOG_DEBUG("BLE_BAS_EVT_NOTIFICATION_ENABLED \n");
            break;

        case BLE_BAS_EVT_NOTIFICATION_DISABLED:
            NRF_LOG_DEBUG("BLE_BAS_EVT_NOTIFICATION_DISABLED \n");
            break;

        default:
            break;
    }
}

int batteryBleInit(void) {
    // Initialize Battery Service.
    ble_bas_init_t basInit;
    memset(&basInit, 0, sizeof(basInit));

    // Security level for the Battery Service
    basInit.bl_rd_sec        = SEC_OPEN;
    basInit.bl_cccd_wr_sec   = SEC_OPEN;
    basInit.bl_report_rd_sec = SEC_OPEN;

    basInit.evt_handler          = _batteryBleEvtHandler;
    basInit.support_notification = true;
    basInit.p_report_ref         = NULL;
    basInit.initial_batt_level   = INVALID_BATTERY_LEVEL;

    const ret_code_t errCode = ble_bas_init(&_gBleBas, &basInit);
    if (errCode != NRF_SUCCESS) {
        NRF_LOG_WARNING("ble_bas_init() failed\n");
        return ERROR_BLE_BAS_INITIALIZE_FAIL;
    }
    
    _gBleBasInitialized = true;

    return 0;
}

int batteryBleUpdate(void) {
    if (!_gBleBasInitialized) {
        return ERROR_BLE_BAS_UNINITIALIZED;
    }

    const int mv          = batteryVoltageGet();
    const uint8_t percent = batteryVoltage2Percent(mv);
    ret_code_t errCode    = ble_bas_battery_level_update(&_gBleBas, percent, BLE_CONN_HANDLE_ALL);
    if (errCode != NRF_SUCCESS) {
        NRF_LOG_WARNING("ble_bas_battery_level_update() failed errCode=0x%x\n", errCode);
        return ERROR_BLE_BAS_UPDATE_FAIL;
    }

    NRF_LOG_DEBUG("mv=%d, percent=%u\n", mv, percent);

    return 0;
}

