///
/// HybridNativeBleNitroSpec.hpp
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
/// https://github.com/mrousavy/nitro
/// Copyright © Marc Rousavy @ Margelo
///

#pragma once

#if __has_include(<NitroModules/HybridObject.hpp>)
#include <NitroModules/HybridObject.hpp>
#else
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
#endif

// Forward declaration of `BLEDevice` to properly resolve imports.
namespace margelo::nitro::co::zyke::ble { struct BLEDevice; }
// Forward declaration of `ScanFilter` to properly resolve imports.
namespace margelo::nitro::co::zyke::ble { struct ScanFilter; }
// Forward declaration of `AndroidConnectionPriority` to properly resolve imports.
namespace margelo::nitro::co::zyke::ble { enum class AndroidConnectionPriority; }
// Forward declaration of `BLEState` to properly resolve imports.
namespace margelo::nitro::co::zyke::ble { enum class BLEState; }
// Forward declaration of `OperationResult` to properly resolve imports.
namespace margelo::nitro::co::zyke::ble { struct OperationResult; }

#include <string>
#include <optional>
#include "BLEDevice.hpp"
#include <vector>
#include <functional>
#include "ScanFilter.hpp"
#include <NitroModules/Null.hpp>
#include <variant>
#include "AndroidConnectionPriority.hpp"
#include <NitroModules/ArrayBuffer.hpp>
#include "BLEState.hpp"
#include "OperationResult.hpp"
#include <NitroModules/Promise.hpp>

namespace margelo::nitro::co::zyke::ble {

  using namespace margelo::nitro;

  /**
   * An abstract base class for `NativeBleNitro`
   * Inherit this class to create instances of `HybridNativeBleNitroSpec` in C++.
   * You must explicitly call `HybridObject`'s constructor yourself, because it is virtual.
   * @example
   * ```cpp
   * class HybridNativeBleNitro: public HybridNativeBleNitroSpec {
   * public:
   *   HybridNativeBleNitro(...): HybridObject(TAG) { ... }
   *   // ...
   * };
   * ```
   */
  class HybridNativeBleNitroSpec: public virtual HybridObject {
    public:
      // Constructor
      explicit HybridNativeBleNitroSpec(): HybridObject(TAG) { }

      // Destructor
      ~HybridNativeBleNitroSpec() override = default;

    public:
      // Properties
      virtual std::optional<std::string> getRestoreStateIdentifier() = 0;
      virtual void setRestoreStateIdentifier(const std::optional<std::string>& restoreStateIdentifier) = 0;

    public:
      // Methods
      virtual void setRestoreStateCallback(const std::function<void(const std::vector<BLEDevice>& /* restoredPeripherals */)>& callback) = 0;
      virtual void iosLazyInit() = 0;
      virtual void startScan(const ScanFilter& filter, const std::function<void(const std::optional<std::variant<nitro::NullType, BLEDevice>>& /* device */, const std::optional<std::variant<nitro::NullType, std::string>>& /* error */)>& callback) = 0;
      virtual bool stopScan() = 0;
      virtual bool isScanning() = 0;
      virtual std::vector<BLEDevice> getConnectedDevices(const std::vector<std::string>& services) = 0;
      virtual void connect(const std::string& deviceId, const std::function<void(bool /* success */, const std::string& /* deviceId */, const std::string& /* error */)>& callback, const std::optional<std::function<void(const std::string& /* deviceId */, bool /* interrupted */, const std::string& /* error */)>>& disconnectCallback, std::optional<bool> autoConnectAndroid) = 0;
      virtual void disconnect(const std::string& deviceId, const std::function<void(bool /* success */, const std::string& /* error */)>& callback) = 0;
      virtual bool isConnected(const std::string& deviceId) = 0;
      virtual double requestMTU(const std::string& deviceId, double mtu) = 0;
      virtual bool requestConnectionPriority(const std::string& deviceId, AndroidConnectionPriority androidConnectionPriority) = 0;
      virtual void readRSSI(const std::string& deviceId, const std::function<void(bool /* success */, double /* rssi */, const std::string& /* error */)>& callback) = 0;
      virtual void discoverServices(const std::string& deviceId, const std::function<void(bool /* success */, const std::string& /* error */)>& callback) = 0;
      virtual void discoverServicesWithCharacteristics(const std::string& deviceId, const std::function<void(bool /* success */, const std::string& /* error */)>& callback) = 0;
      virtual std::vector<std::string> getServices(const std::string& deviceId) = 0;
      virtual std::vector<std::string> getCharacteristics(const std::string& deviceId, const std::string& serviceId) = 0;
      virtual void readCharacteristic(const std::string& deviceId, const std::string& serviceId, const std::string& characteristicId, const std::function<void(bool /* success */, const std::shared_ptr<ArrayBuffer>& /* data */, const std::string& /* error */)>& callback) = 0;
      virtual void writeCharacteristic(const std::string& deviceId, const std::string& serviceId, const std::string& characteristicId, const std::shared_ptr<ArrayBuffer>& data, bool withResponse, const std::function<void(bool /* success */, const std::shared_ptr<ArrayBuffer>& /* responseData */, const std::string& /* error */)>& callback) = 0;
      virtual void subscribeToCharacteristic(const std::string& deviceId, const std::string& serviceId, const std::string& characteristicId, const std::function<void(const std::string& /* characteristicId */, const std::shared_ptr<ArrayBuffer>& /* data */)>& updateCallback, const std::function<void(bool /* success */, const std::string& /* error */)>& completionCallback) = 0;
      virtual void unsubscribeFromCharacteristic(const std::string& deviceId, const std::string& serviceId, const std::string& characteristicId, const std::function<void(bool /* success */, const std::string& /* error */)>& callback) = 0;
      virtual bool isSubscribedToCharacteristic(const std::string& deviceId, const std::string& serviceId, const std::string& characteristicId) = 0;
      virtual void requestBluetoothEnable(const std::function<void(bool /* success */, const std::string& /* error */)>& callback) = 0;
      virtual BLEState state() = 0;
      virtual OperationResult subscribeToStateChange(const std::function<void(BLEState /* state */)>& stateCallback) = 0;
      virtual OperationResult unsubscribeFromStateChange() = 0;
      virtual std::shared_ptr<Promise<void>> openSettings() = 0;

    protected:
      // Hybrid Setup
      void loadHybridMethods() override;

    protected:
      // Tag for logging
      static constexpr auto TAG = "NativeBleNitro";
  };

} // namespace margelo::nitro::co::zyke::ble
