/*
 * Copyright 2017-2026 Espressif Systems (Shanghai) PTE LTD
 * Copyright 2017 Neil Kolban
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * BLE2902.h
 *
 *  Created on: Jun 25, 2017
 *      Author: kolban
 *
 *  Modified on: Feb 28, 2025
 *      Author: lucasssvaz (based on kolban's and h2zero's work)
 *      Description: Added support for NimBLE
 */

#ifndef COMPONENTS_CPP_UTILS_BLE2902_H_
#define COMPONENTS_CPP_UTILS_BLE2902_H_

#include "soc/soc_caps.h"
#include "sdkconfig.h"
#if defined(SOC_BLE_SUPPORTED) || defined(CONFIG_ESP_HOSTED_ENABLE_BT_NIMBLE)
#if defined(CONFIG_BLUEDROID_ENABLED) || defined(CONFIG_NIMBLE_ENABLED)

/***************************************************************************
 *                           Common includes                               *
 ***************************************************************************/

#include "BLEDescriptor.h"

#if defined(CONFIG_BLUEDROID_ENABLED)
#include "BLEAddress.h"
#endif

/**
 * @brief Descriptor for Client Characteristic Configuration.
 *
 * This is a convenience descriptor for the Client Characteristic Configuration which has a UUID of 0x2902.
 *
 * See also:
 * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
 */

// Class declaration for Bluedroid
#if defined(CONFIG_BLUEDROID_ENABLED)
class BLE2902 : public BLEDescriptor {
#endif

// Class declaration for NimBLE (deprecated)
#if defined(CONFIG_NIMBLE_ENABLED)
  class [[deprecated("NimBLE does not support manually adding 2902 descriptors as they \
are automatically added when the characteristic has notifications or indications enabled. \
Get/Set the notifications/indications properties of the characteristic instead. \
This class will be removed in a future version.")]] BLE2902 : public BLEDescriptor {
#endif

  public:
    /***************************************************************************
   *                         Common public functions                         *
   ***************************************************************************/

    BLE2902();
    bool getNotifications();
    bool getIndications();
    void setNotifications(bool flag);
    void setIndications(bool flag);

#if defined(CONFIG_BLUEDROID_ENABLED)
    /***************************************************************************
     *                       Bluedroid CCCD persistence                        *
     ***************************************************************************/

    /**
     * @brief Persist CCCD value to NVS for a bonded device.
     * @param [in] peerAddress The address of the bonded peer device.
     * @param [in] charHandle The handle of the characteristic this CCCD belongs to.
     * @return true if the value was successfully persisted, false otherwise.
     */
    bool persistValue(const BLEAddress &peerAddress, uint16_t charHandle);

    /**
     * @brief Restore CCCD value from NVS for a bonded device.
     * @param [in] peerAddress The address of the bonded peer device.
     * @param [in] charHandle The handle of the characteristic this CCCD belongs to.
     * @return true if the value was successfully restored, false otherwise.
     */
    bool restoreValue(const BLEAddress &peerAddress, uint16_t charHandle);

    /**
     * @brief Delete persisted CCCD value from NVS for a device.
     * @param [in] peerAddress The address of the peer device.
     * @param [in] charHandle The handle of the characteristic this CCCD belongs to.
     * @return true if the value was successfully deleted, false otherwise.
     */
    static bool deletePersistedValue(const BLEAddress &peerAddress, uint16_t charHandle);

    /**
     * @brief Delete all persisted CCCD values from NVS.
     * @return true if all values were successfully deleted, false otherwise.
     */
    static bool deleteAllPersistedValues();

  private:
    static String getNvsKey(const BLEAddress &peerAddress, uint16_t charHandle);
#endif
  };  // BLE2902

#endif /* CONFIG_BLUEDROID_ENABLED || CONFIG_NIMBLE_ENABLED */
#endif /* SOC_BLE_SUPPORTED || CONFIG_ESP_HOSTED_ENABLE_BT_NIMBLE */

#endif /* COMPONENTS_CPP_UTILS_BLE2902_H_ */
