// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_GAP_LOW_ENERGY_DISCOVERY_MANAGER_H_
#define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_GAP_LOW_ENERGY_DISCOVERY_MANAGER_H_

#include <lib/async/dispatcher.h>
#include <lib/fit/function.h>

#include <memory>
#include <queue>
#include <unordered_set>

#include "src/connectivity/bluetooth/core/bt-host/common/byte_buffer.h"
#include "src/connectivity/bluetooth/core/bt-host/common/device_address.h"
#include "src/connectivity/bluetooth/core/bt-host/gap/discovery_filter.h"
#include "src/connectivity/bluetooth/core/bt-host/gap/gap.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/low_energy_scanner.h"
#include "src/lib/fxl/memory/ref_ptr.h"
#include "src/lib/fxl/memory/weak_ptr.h"
#include "src/lib/fxl/synchronization/thread_checker.h"

namespace bt {

namespace hci {
class LowEnergyScanner;
class Transport;
}  // namespace hci

namespace gap {

class LowEnergyDiscoveryManager;
class Peer;
class PeerCache;

// LowEnergyDiscoveryManager implements GAP LE central/observer role
// discovery procedures. This class provides mechanisms for multiple clients to
// simultaneously scan for nearby peers filtered by adveritising data
// contents. This class also provides hooks for other layers to manage the
// Adapter's scan state for other procedures that require it (e.g. connection
// establishment, pairing procedures, and other scan and advertising
// procedures).
// TODO(armansito): The last sentence of this paragraph hasn't been implemented
// yet.
//
// An instance of LowEnergyDiscoveryManager can be initialized in either
// "legacy" or "extended" mode. The legacy mode is intended for Bluetooth
// controllers that only support the pre-5.0 HCI scan command set. The extended
// mode is intended for Bluetooth controllers that claim to support the "LE
// Extended Advertising" feature.
//
// Only one instance of LowEnergyDiscoveryManager should be created per
// hci::Transport object as multiple instances cannot correctly maintain state
// if they operate concurrently.
//
// To request a session, a client calls StartDiscovery() and asynchronously
// obtains a LowEnergyDiscoverySession that it uniquely owns. The session object
// can be configured with a callback to receive scan results. The session
// maintains an internal filter that may be modified to restrict the scan
// results based on properties of received advertisements.
//
// PROCEDURE:
//
// Starting the first discovery session initiates a periodic scan procedure, in
// which the scan is stopped and restarted for a given scan period (10.24
// seconds by default). This continues until all sessions have been removed.
//
// By default duplicate filtering is used which means that a new advertising
// report will be generated for each discovered advertiser only once per scan
// period. Scan results for each scan period are cached so that sessions added
// during a scan period can receive previously processed results.
//
// EXAMPLE:
//     bt::gap::LowEnergyDiscoveryManager discovery_manager(
//         bt::gap::LowEnergyDiscoveryManager::Mode::kLegacy,
//         transport, dispatcher);
//     ...
//
//     std::unique_ptr<bt::gap::LowEnergyDiscoverySession> session;
//     discovery_manager.StartDiscovery([&session](auto new_session) {
//       // Take ownership of the session to make sure it isn't terminated when
//       // this callback returns.
//       session = std::move(new_session);
//
//       // Only scan for peers advertising the "Heart Rate" GATT Service.
//       uint16_t uuid = 0x180d;
//       session->filter()->set_service_uuids({bt::UUID(uuid)});
//       session->SetResultCallback([](const
//       bt::hci::LowEnergyScanResult& result,
//                                     const bt::ByteBuffer&
//                                     advertising_data) {
//         // Do stuff with |result| and |advertising_data|. (|advertising_data|
//         // contains any received Scan Response data as well).
//       });
//     });
//
// NOTE: These classes are not thread-safe. An instance of
// LowEnergyDiscoveryManager is bound to its creation thread and the associated
// dispatcher and must be accessed and destroyed on the same thread.

// Represents a LE discovery session initiated via
// LowEnergyDiscoveryManager::StartDiscovery(). Instances cannot be created
// directly; instead they are handed to callers by LowEnergyDiscoveryManager.
//
// The discovery classes are not thread-safe. A LowEnergyDiscoverySession MUST
// be accessed and destroyed on the thread that it was created on.
class LowEnergyDiscoverySession final {
 public:
  // Destroying a session instance automatically ends the session. To terminate
  // a session, a client may either explicitly call Stop() or simply destroy
  // this instance.
  ~LowEnergyDiscoverySession();

  // Sets a callback for receiving notifications on newly discovered peers.
  // |data| contains advertising and scan response data (if any) obtained during
  // discovery.
  //
  // When this callback is set, it will immediately receive notifications for
  // the cached results from the most recent scan period. If a filter was
  // assigned earlier, then the callback will only receive results that match
  // the filter.
  using PeerFoundCallback = fit::function<void(const Peer& peer)>;
  void SetResultCallback(PeerFoundCallback callback);

  // Sets a callback to get notified when the session becomes inactive due to an
  // internal error.
  void set_error_callback(fit::closure callback) {
    error_callback_ = std::move(callback);
  }

  // Returns the filter that belongs to this session. The caller may modify the
  // filter as desired. By default no peers are filtered.
  //
  // NOTE: The client is responsible for setting up the filter's "flags" field
  // for discovery procedures.
  DiscoveryFilter* filter() { return &filter_; }

  // Ends this session. This instance will stop receiving notifications for
  // peers.
  void Stop();

  // Returns true if this session is active. A session is considered inactive
  // after a call to Stop().
  bool active() const { return active_; }

 private:
  friend class LowEnergyDiscoveryManager;

  // Called by LowEnergyDiscoveryManager.
  explicit LowEnergyDiscoverySession(
      fxl::WeakPtr<LowEnergyDiscoveryManager> manager);

  // Called by LowEnergyDiscoveryManager on newly discovered scan results.
  void NotifyDiscoveryResult(const Peer& peer) const;

  // Marks this session as inactive and notifies the error handler.
  void NotifyError();

  bool active_;
  fxl::WeakPtr<LowEnergyDiscoveryManager> manager_;
  fit::closure error_callback_;
  PeerFoundCallback peer_found_callback_;
  DiscoveryFilter filter_;
  fxl::ThreadChecker thread_checker_;

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(LowEnergyDiscoverySession);
};

using LowEnergyDiscoverySessionPtr = std::unique_ptr<LowEnergyDiscoverySession>;

// See comments above.
class LowEnergyDiscoveryManager final : public hci::LowEnergyScanner::Delegate {
 public:
  // |peer_cache| MUST out-live this LowEnergyDiscoveryManager.
  LowEnergyDiscoveryManager(fxl::RefPtr<hci::Transport> hci,
                            hci::LowEnergyScanner* scanner,
                            PeerCache* peer_cache);
  virtual ~LowEnergyDiscoveryManager();

  // Starts a new discovery session and reports the result via |callback|. If a
  // session has been successfully started the caller will receive a new
  // LowEnergyDiscoverySession instance via |callback| which it uniquely owns.
  // On failure a nullptr will be returned via |callback|.
  //
  // TODO(armansito): Implement option to disable duplicate filtering. Would
  // this require software filtering for clients that did not request it?
  using SessionCallback = fit::function<void(LowEnergyDiscoverySessionPtr)>;
  void StartDiscovery(SessionCallback callback);

  // Enable or disable the background scan feature. When enabled, the discovery
  // manager will perform a low duty-cycle passive scan when no discovery
  // sessions are active.
  void EnableBackgroundScan(bool enable);

  // Sets a new scan period to any future and ongoing discovery procedures.
  void set_scan_period(zx::duration period) { scan_period_ = period; }

  // Returns whether there is an active discovery session.
  bool discovering() const { return !sessions_.empty(); }

  // Registers a callback which runs when a connectable advertisement is
  // received from a bonded peer.
  //
  // Note: this callback can be triggered during a background scan as well as
  // general discovery.
  using BondedPeerConnectableCallback = fit::function<void(PeerId id)>;
  void set_bonded_peer_connectable_callback(
      BondedPeerConnectableCallback callback) {
    bonded_conn_cb_ = std::move(callback);
  }

 private:
  friend class LowEnergyDiscoverySession;

  const PeerCache* peer_cache() const { return peer_cache_; }

  const std::unordered_set<PeerId>& cached_scan_results() const {
    return cached_scan_results_;
  }

  // Creates and stores a new session object and returns it.
  std::unique_ptr<LowEnergyDiscoverySession> AddSession();

  // Called by LowEnergyDiscoverySession to stop a session that it was assigned
  // to.
  void RemoveSession(LowEnergyDiscoverySession* session);

  // hci::LowEnergyScanner::Delegate override:
  void OnPeerFound(const hci::LowEnergyScanResult& result,
                   const ByteBuffer& data) override;
  void OnDirectedAdvertisement(const hci::LowEnergyScanResult& result) override;

  // Called by hci::LowEnergyScanner
  void OnScanStatus(hci::LowEnergyScanner::ScanStatus status);

  // Tells the scanner to start scanning. Aliases are provided for improved
  // readability.
  void StartScan(bool active);
  inline void StartActiveScan() { StartScan(true); }
  inline void StartPassiveScan() { StartScan(false); }

  // Used by destructor to handle all sessions
  void DeactivateAndNotifySessions();

  // The dispatcher that we use for invoking callbacks asynchronously.
  async_dispatcher_t* dispatcher_;

  // The peer cache that we use for storing and looking up scan results. We
  // hold a raw pointer as we expect this to out-live us.
  PeerCache* const peer_cache_;

  // True if background scanning is enabled.
  bool background_scan_enabled_;

  // Called when a directed connectable advertisement is received during an
  // active or passive scan.
  BondedPeerConnectableCallback bonded_conn_cb_;

  // The list of currently pending calls to start discovery.
  std::queue<SessionCallback> pending_;

  // The list of currently active/known sessions. We store raw (weak) pointers
  // here because, while we don't actually own the session objects they will
  // always notify us before destruction so we can remove them from this list.
  //
  // The number of elements in |sessions_| acts as our scan reference count.
  // When |sessions_| becomes empty scanning is stopped. Similarly, scanning is
  // started on the insertion of the first element.
  std::unordered_set<LowEnergyDiscoverySession*> sessions_;

  // Identifiers for the cached scan results for the current scan period during
  // discovery. The minimum (and default) scan period is 10.24 seconds
  // when performing LE discovery. This can cause a long wait for a discovery
  // session that joined in the middle of a scan period and duplicate filtering
  // is enabled. We maintain this cache to immediately notify new sessions of
  // the currently cached results for this period.
  std::unordered_set<PeerId> cached_scan_results_;

  // The value (in ms) that we use for the duration of each scan period.
  zx::duration scan_period_ = kLEGeneralDiscoveryScanMin;

  // The scanner that performs the HCI procedures. |scanner_| must out-live this
  // discovery manager.
  hci::LowEnergyScanner* scanner_;  // weak

  fxl::ThreadChecker thread_checker_;

  // Keep this as the last member to make sure that all weak pointers are
  // invalidated before other members get destroyed.
  fxl::WeakPtrFactory<LowEnergyDiscoveryManager> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(LowEnergyDiscoveryManager);
};

}  // namespace gap
}  // namespace bt

#endif  // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_GAP_LOW_ENERGY_DISCOVERY_MANAGER_H_
