/*
 * Copyright (c) 2026 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
 */

/**
 *
 * @defgroup ble_gatt Bluetooth GATT interface
 * @{
 * @ingroup ble
 *
 *
 */
#ifndef __BLE_GATT_H__
#define __BLE_GATT_H__

#include "ble_common.h"
#include <stddef.h>
#include <zephyr/kernel.h>
#include <zephyr/bluetooth/bluetooth.h>

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */


#define BLE_RX_BUFFER_SIZE              256

#define BLE_DEFAULT_PASSKEY             123456U
#define BLE_TIMEOUT_MS                  20000

#define BLE_ADV_TIMEOUT_MS              20000
#define BLE_CONNECTED_DELAY_MS          12000

#define BLE_AVAILABILITY_TIMEOUT_MS     10000
#define BLE_POWER_ON_RETRY_MS          (30 * 60 * 1000)             //(30 * 60 * 1000)
#define BLE_POWER_ON_WAIT_MS           BLE_TIMEOUT_MS

#define PROTOCOL_SEND_MAX_RETRIES    3
#define PROTOCOL_SEND_RETRY_DELAY_MS 100

extern struct k_work_delayable ble_timeout_work;
extern bool ble_connected;

typedef int (*ble_ready_callback_t)(uint8_t);

/**
 * @brief BLE data received callback, this callback will be called when new data is received from the BLE GATT profile
 *
 * @param data          Received data
 * @param len           Length of the received data
 */
typedef void (*ble_data_received_cb_t)(const char *data, size_t len);

/**
 * @brief Initialize BLE GATT profile and start advertising
 *
 * @param data_received_cb  Data received callback @ref ble_data_received_cb_t
 *
 * @return Operation status, 0 for success
 */
int ble_gatt_init(ble_data_received_cb_t data_received_cb);

/**
 * @brief Send Neuton inference result over BLE GATT profile
 *
 * @param data      BLE data to send
 * @param len       Data size in bytes
 *
 * @return Operation status, 0 for success
 */
int ble_gatt_send_raw_data(const uint8_t *data, size_t len);


/**
 * @brief Start BLE advertising
 *
 * @return Operation status, 0 for success
 */
int ble_gatt_start_advertising(void);

/**
 * @brief Get RSSI of the current connection
 *
 * @param out_rssi  Pointer to store RSSI value, can be NULL
 *
 * @return Operation status, 0 for success
 */

int ble_gatt_get_rssi(int8_t *out_rssi);

void ble_data_received(const char *data, size_t len);

int passkey_from_payload(const uint8_t *payload, uint32_t *passkey);
int ble_hid_set_passkey(uint32_t passkey);

int ble_user_entered_passkey(uint32_t passkey);

int ble_availability_check(void);
int ble_reset_passkey_to_default(void);

int ble_gatt_disconnect_and_stop_advertising(void);
void ble_timeout_work_handler(struct k_work *work);
int ble_start_advertising_with_timeout(void);

void ble_power_on_retry_start(void);
void ble_power_on_retry_cancel(void);

void power_on_seq(void);
void bt_ready(int err);
void power_on_ble_connected(void);
bool ble_gatt_is_ready(void);

int ble_wait_for_notifications(uint32_t timeout_ms);
int ble_wait_until_ready(uint32_t timeout_ms);

bool ble_notifications_enabled(void);
bool ble_is_ready_for_data(void);
int ble_wait_until_ready_for_data(uint32_t timeout_ms);

void ble_disconnect_work_handler(struct k_work *work);
void ble_connected_work_handler(struct k_work *work);
void ble_adv_timeout_handler(struct k_work *work);


int ble_start_sequence(ble_ready_callback_t callback, uint8_t arg);
/* Same, but may preempt a running FOTA window (fall alert only). */
int ble_start_sequence_urgent(ble_ready_callback_t callback, uint8_t arg);
void ble_sequence_cancel(void);

/* FOTA window (driven by fota.c) */
int  ble_gatt_fota_enter(void);
void ble_gatt_fota_exit(void);
bool ble_gatt_fota_mode(void);
bool ble_gatt_sequence_busy(void);

void ble_send_delay_handler(struct k_work *work);
void ble_packet_send_work_handler(struct k_work *work);

#ifdef __cplusplus
}
#endif /* __cplusplus */


#endif /* __BLE_GATT_H__ */

/**
 * @}
 */
