// 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 <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 <unordered_set>

#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_
