// Copyright 2018 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_EXAMPLES_BT_LE_HEART_RATE_PERIPHERAL_SERVICE_H_
#define SRC_CONNECTIVITY_BLUETOOTH_EXAMPLES_BT_LE_HEART_RATE_PERIPHERAL_SERVICE_H_

#include <unordered_set>

#include <fuchsia/bluetooth/gatt/cpp/fidl.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/fidl/cpp/string.h>
#include <lib/fidl/cpp/vector.h>
#include <src/lib/fxl/memory/weak_ptr.h>

namespace bt_le_heart_rate {

class HeartModel;

class Service final : fuchsia::bluetooth::gatt::LocalServiceDelegate {
 public:
  // See assigned numbers for GATT services and characteristics.
  // https://www.bluetooth.com/specifications/gatt/services
  // https://www.bluetooth.com/specifications/gatt/characteristics
  static constexpr char kServiceUuid[] = "0000180d-0000-1000-8000-00805f9b34fb";
  static constexpr uint64_t kHeartRateMeasurementId = 0;
  static constexpr char kHeartRateMeasurementUuid[] =
      "00002a37-0000-1000-8000-00805f9b34fb";
  static constexpr uint64_t kBodySensorLocationId = 1;
  static constexpr char kBodySensorLocationUuid[] =
      "00002a38-0000-1000-8000-00805f9b34fb";
  static constexpr uint64_t kHeartRateControlPointId = 2;
  static constexpr char kHeartRateControlPointUuid[] =
      "00002a39-0000-1000-8000-00805f9b34fb";

  // See Assigned Numbers for Heart Rate Service
  // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.heart_rate.xml
  static constexpr fuchsia::bluetooth::gatt::ErrorCode
      CONTROL_POINT_NOT_SUPPORTED =
          static_cast<fuchsia::bluetooth::gatt::ErrorCode>(0x80);

  // Heart Rate Service v1.0, 3.3.1 [Control Point] Characteristic Behavior.
  static constexpr uint8_t kResetEnergyExpendedValue = 0x01;

  explicit Service(std::unique_ptr<HeartModel> heart_model);
  ~Service() = default;

  void PublishService(fuchsia::bluetooth::gatt::ServerPtr* gatt_server);

  void set_measurement_interval(int msec) { measurement_interval_ = msec; }

 private:
  void NotifyMeasurement();

  void ScheduleNotification();

  // Implement LocalServiceDelegate.
  void OnCharacteristicConfiguration(uint64_t characteristic_id,
                                     std::string peer_id, bool notify,
                                     bool indicate) override;
  void OnReadValue(uint64_t id, int32_t offset,
                   OnReadValueCallback callback) override;
  void OnWriteValue(uint64_t id, uint16_t offset, std::vector<uint8_t> value,
                    OnWriteValueCallback callback) override;
  void OnWriteWithoutResponse(uint64_t id, uint16_t offset,
                              std::vector<uint8_t> value) override;

  std::unique_ptr<HeartModel> heart_model_;
  fidl::Binding<fuchsia::bluetooth::gatt::LocalServiceDelegate> binding_;
  fuchsia::bluetooth::gatt::LocalServicePtr service_;

  // Peers that have enabled measurement notifications.
  std::unordered_set<std::string> measurement_peers_;
  bool notify_scheduled_;

  // Interval of measurement notifications in milliseconds.
  int measurement_interval_ = 2000;

  fxl::WeakPtrFactory<Service> weak_factory_;
};

// Interface for heart rate measurement sensors
class HeartModel {
 public:
  struct Measurement {
    bool contact;         // True if measured while sensor was in contact.
    int rate;             // Heart rate in beats per minute (BPM).
    int energy_expended;  // Energy expended since reset in kilojoules (kJ).
  };

  virtual ~HeartModel() {}

  virtual bool ReadMeasurement(Measurement* measurement) = 0;

  virtual void ResetEnergyExpended() = 0;
};

enum class BodySensorLocation : uint8_t {
  kOther = 0,
  kChest = 1,
  kWrist = 2,
  kFinger = 3,
  kHand = 4,
  kEarLobe = 5,
  kFoot = 6,
};

}  // namespace bt_le_heart_rate

#endif  // SRC_CONNECTIVITY_BLUETOOTH_EXAMPLES_BT_LE_HEART_RATE_PERIPHERAL_SERVICE_H_
