// 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_HCI_LEGACY_LOW_ENERGY_SCANNER_H_
#define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_HCI_LEGACY_LOW_ENERGY_SCANNER_H_

#include <lib/async/cpp/task.h>
#include <lib/async/dispatcher.h>
#include <lib/fit/thread_checker.h>

#include <memory>
#include <unordered_map>

#include "src/connectivity/bluetooth/core/bt-host/common/byte_buffer.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/command_channel.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/hci.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/low_energy_scanner.h"
#include "src/lib/fxl/memory/ref_counted.h"

namespace bt::hci {

class LocalAddressDelegate;

// LegacyLowEnergyScanner implements the LowEnergyScanner interface for
// controllers that do not support the 5.0 Extended Advertising feature. This
// uses the legacy HCI LE scan commands and events:
//     - HCI_LE_Set_Scan_Parameters
//     - HCI_LE_Set_Scan_Enable
//     - HCI_LE_Advertising_Report event
class LegacyLowEnergyScanner : public LowEnergyScanner {
 public:
  LegacyLowEnergyScanner(LocalAddressDelegate* local_addr_delegate, fxl::WeakPtr<Transport> hci,
                         async_dispatcher_t* dispatcher);
  ~LegacyLowEnergyScanner() override;

  // LowEnergyScanner overrides:
  bool StartScan(const ScanOptions& options, ScanStatusCallback callback) override;
  bool StopScan() override;

 private:
  // This represents the data obtained for a scannable advertisement for which a scan response has
  // not yet been received. Clients are notified for scannable advertisement either when the
  // corresponding scan response is received or, otherwise, a timeout expires.
  class PendingScanResult {
   public:
    // |adv|: Initial advertising data payload.
    PendingScanResult(LowEnergyScanResult result, const ByteBuffer& adv, zx::duration timeout,
                      fit::closure timeout_handler);

    // Return the contents of the data.
    BufferView data() const { return buffer_.view(0, data_size_); }

    const LowEnergyScanResult& result() const { return result_; }

    void set_rssi(int8_t rssi) { result_.rssi = rssi; }
    void set_resolved(bool resolved) { result_.resolved = resolved; }

    // Appends |data| to the end of the current contents.
    void Append(const ByteBuffer& data);

   private:
    LowEnergyScanResult result_;

    // The size of the data so far accumulated in |buffer_|.
    size_t data_size_ = 0u;

    // Buffer large enough to store both advertising and scan response payloads.
    StaticByteBuffer<kMaxLEAdvertisingDataLength * 2> buffer_;

    // Since not all scannable advertisements are always followed by a scan response, we report a
    // pending result if a scan response is not received within a timeout.
    async::TaskClosure timeout_task_;
  };

  // Called by StartScan() after the local peer address has been obtained.
  void StartScanInternal(const DeviceAddress& local_address, const ScanOptions& options,
                         ScanStatusCallback callback);

  // Called by StopScan() and by the scan timeout handler set up by StartScan().
  void StopScanInternal(bool stopped);

  // Event handler for HCI LE Advertising Report event.
  CommandChannel::EventCallbackResult OnAdvertisingReportEvent(const EventPacket& event);

  // Called when a Scan Response is received during an active scan.
  void HandleScanResponse(const LEAdvertisingReportData& report, int8_t rssi);

  // Notifies observers of a peer that was found.
  void NotifyPeerFound(const LowEnergyScanResult& result, const ByteBuffer& data);

  // Called when the scan timeout task executes.
  void OnScanPeriodComplete();

  // Called when the scan response timeout expires for the given device address.
  void OnScanResponseTimeout(const DeviceAddress& address);

  // Used to obtain the local peer address type to use during scanning.
  LocalAddressDelegate* local_addr_delegate_;  // weak

  // Callback passed in to the most recently accepted call to StartScan();
  ScanStatusCallback scan_cb_;

  // The scan period timeout handler for the currently active scan session.
  async::TaskClosure scan_timeout_task_;

  // Maximum time duration for which a scannable advertisement will be stored and not reported to
  // clients until a corresponding scan response is received.
  zx::duration scan_response_timeout_;

  // Our event handler ID for the LE Advertising Report event.
  CommandChannel::EventHandlerId event_handler_id_;

  // Scannable advertising events for which a Scan Response PDU has not been
  // received. This is accumulated during a discovery procedure and always
  // cleared at the end of the scan period.
  std::unordered_map<DeviceAddress, std::unique_ptr<PendingScanResult>> pending_results_;
  fit::thread_checker thread_checker_;

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(LegacyLowEnergyScanner);
};

}  // namespace bt::hci

#endif  // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_HCI_LEGACY_LOW_ENERGY_SCANNER_H_
