// 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_ADVERTISING_MANAGER_H_
#define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_GAP_LOW_ENERGY_ADVERTISING_MANAGER_H_

#include <lib/fit/function.h>

#include "src/connectivity/bluetooth/core/bt-host/common/advertising_data.h"
#include "src/connectivity/bluetooth/core/bt-host/common/identifier.h"
#include "src/connectivity/bluetooth/core/bt-host/gap/gap.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/hci_constants.h"
#include "src/connectivity/bluetooth/core/bt-host/hci/low_energy_advertiser.h"
#include "src/lib/fxl/memory/weak_ptr.h"

namespace bt {

namespace hci {
class Connection;
class LocalAddressDelegate;
class Transport;
}  // namespace hci

namespace gap {

using AdvertisementId = Identifier<uint64_t>;
constexpr AdvertisementId kInvalidAdvertisementId(0u);

class LowEnergyAdvertisingManager;

// Represents an active advertising instance. Stops the associated advertisement upon destruction.
class AdvertisementInstance final {
 public:
  // The default constructor initializes an instance with an invalid ID.
  AdvertisementInstance();
  ~AdvertisementInstance();

  AdvertisementInstance(AdvertisementInstance&& other) { Move(&other); }
  AdvertisementInstance& operator=(AdvertisementInstance&& other) {
    Move(&other);
    return *this;
  }

  AdvertisementId id() const { return id_; }

 private:
  friend class LowEnergyAdvertisingManager;

  AdvertisementInstance(AdvertisementId id, fxl::WeakPtr<LowEnergyAdvertisingManager> owner);
  void Move(AdvertisementInstance* other);
  void Reset();

  AdvertisementId id_;
  fxl::WeakPtr<LowEnergyAdvertisingManager> owner_;

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(AdvertisementInstance);
};

// Enum values for determining the advertising interval range. These ranges come from Core
// Specification v5.1, Vol 3, Part C, Appendix A (see also the constants defined in gap.h).
enum class AdvertisingInterval {
  FAST1,
  FAST2,
  SLOW,
};

class LowEnergyAdvertisingManager {
 public:
  LowEnergyAdvertisingManager(hci::LowEnergyAdvertiser* advertiser,
                              hci::LocalAddressDelegate* local_addr_delegate);
  virtual ~LowEnergyAdvertisingManager();

  // Returns true if the controller is currently advertising.
  bool advertising() const { return !advertisements_.empty(); }

  // Asynchronously attempts to start advertising a set of |data| with
  // additional scan response data |scan_rsp|.
  //
  // If |connect_callback| is provided, the advertisement will be connectable
  // and it will be called with the returned advertisement_id and a pointer to
  // the new connection, at which point the advertisement will have been
  // stopped.
  //
  // Returns false if the parameters represent an invalid advertisement:
  //  * if |anonymous| is true but |callback| is set
  //
  // |status_callback| may be called synchronously within this function.
  // |status_callback| provides one of:
  //  - an |advertisement_id|, which can be used to stop advertising
  //    or disambiguate calls to |callback|, and a success |status|.
  //  - kInvalidAdvertisementId and an error indication in |status|:
  //    * HostError::kInvalidParameters if the advertising parameters
  //      are invalid (e.g. |data| is too large).
  //    * HostError::kNotSupported if another set cannot be advertised
  //      or if the requested parameters are not supported by the hardware.
  //    * HostError::kProtocolError with a HCI error reported from
  //      the controller, otherwise.
  using ConnectionCallback =
      fit::function<void(AdvertisementId advertisement_id, std::unique_ptr<hci::Connection> link)>;
  using AdvertisingStatusCallback =
      fit::function<void(AdvertisementInstance instance, hci::Status status)>;
  void StartAdvertising(AdvertisingData data, AdvertisingData scan_rsp,
                        ConnectionCallback connect_callback, AdvertisingInterval interval,
                        bool anonymous, bool include_tx_power_level,
                        AdvertisingStatusCallback status_callback);

  // Stop advertising the advertisement with the id |advertisement_id|
  // Returns true if an advertisement was stopped, and false otherwise.
  // This function is idempotent.
  bool StopAdvertising(AdvertisementId advertisement_id);

 private:
  class ActiveAdvertisement;

  // Active advertisements, indexed by id.
  // TODO(armansito): Use fbl::HashMap here (NET-176) or move
  // ActiveAdvertisement definition here and store by value (it is a small
  // object).
  std::unordered_map<AdvertisementId, std::unique_ptr<ActiveAdvertisement>> advertisements_;

  // Used to communicate with the controller. |advertiser_| must outlive this
  // advertising manager.
  hci::LowEnergyAdvertiser* advertiser_;  // weak

  // Used to obtain the local device address for advertising. Must outlive this
  // advertising manager.
  hci::LocalAddressDelegate* local_addr_delegate_;  // weak

  // Note: Should remain the last member so it'll be destroyed and
  // invalidate it's pointers before other members are destroyed.
  fxl::WeakPtrFactory<LowEnergyAdvertisingManager> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(LowEnergyAdvertisingManager);
};

}  // namespace gap
}  // namespace bt

#endif  // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_GAP_LOW_ENERGY_ADVERTISING_MANAGER_H_
