#include "ota.h"
#include "advertising.h"
#include "ble_conn_state.h"
#include "ble_dfu.h"
#include "error.h"
#include "nrf_log.h"

#if BLE_DFU_APP_SUPPORT
static void _bleDfuDisconnect(const uint16_t connHandle, void* pContext) {
    UNUSED_PARAMETER(pContext);
    const ret_code_t errCode = sd_ble_gap_disconnect(connHandle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
    if (errCode != NRF_SUCCESS) {
        NRF_LOG_WARNING("Failed to disconnect connection. Connection handle: %d Error: 0x%x\n", connHandle, errCode);
        return;
    }
    
    NRF_LOG_INFO("Disconnected connection handle %d", connHandle);
}

// YOUR_JOB: Update this code if you want to do anything given a DFU event (optional).
/**@brief Function for handling dfu events from the Buttonless Secure DFU service
 *
 * @param[in]   event   Event from the Buttonless Secure DFU service.
 */
static void _bleDfuEvtHandler(ble_dfu_buttonless_evt_type_t event) {
    switch (event) {
        case BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE:
        {
            NRF_LOG_INFO("BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE");

            // Prevent device from advertising on disconnect.
            advertisingModesConfigSet();

            // Disconnect all other bonded devices that currently are connected.
            // This is required to receive a service changed indication
            // on bootup after a successful (or aborted) Device Firmware Update.
            uint32_t conn_count = ble_conn_state_for_each_connected(_bleDfuDisconnect, NULL);
            NRF_LOG_INFO("Disconnected %d links.", conn_count);            
        }
        break;

        case BLE_DFU_EVT_BOOTLOADER_ENTER:
        {
            // YOUR_JOB: Write app-specific unwritten data to FLASH, control finalization of this
            //           by delaying reset by reporting false in app_shutdown_handler
            NRF_LOG_INFO("BLE_DFU_EVT_BOOTLOADER_ENTER\n");
        }    
        break;

        case BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED:
        {
            NRF_LOG_ERROR("BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED\n");
            // YOUR_JOB: Take corrective measures to resolve the issue
            //           like calling APP_ERROR_CHECK to reset the device.
        }    
        break;

        case BLE_DFU_EVT_RESPONSE_SEND_ERROR:
        {
            NRF_LOG_ERROR("BLE_DFU_EVT_RESPONSE_SEND_ERROR\n");
            // YOUR_JOB: Take corrective measures to resolve the issue
            //           like calling APP_ERROR_CHECK to reset the device.
        }    
        break;

        default:
        {
            NRF_LOG_ERROR("Unknown event from ble_dfu_buttonless.");
        }    
        break;
    }
}

int bleDfuInit(void) {
    ret_code_t errCode = ble_dfu_buttonless_async_svci_init();
    if (errCode != NRF_SUCCESS) {
        NRF_LOG_WARNING("ble_dfu_buttonless_async_svci_init() failed, errCode=0x%x\n", errCode);
        return ERROR_OTA_INITIALIZE_FAIL;
    }

    ble_dfu_buttonless_init_t init = {0};
    init.evt_handler = _bleDfuEvtHandler;
    errCode = ble_dfu_buttonless_init(&init);
    if (errCode != NRF_SUCCESS) {
        NRF_LOG_WARNING("ble_dfu_buttonless_init() failed\n");
        return ERROR_OTA_INITIALIZE_FAIL;
    }    

    return 0;
}    
#endif
