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

#include "service.h"

#include <algorithm>
#include <iostream>
#include <iterator>
#include <limits>

#include <lib/async/cpp/task.h>
#include <lib/async/default.h>
#include <src/lib/fxl/logging.h>

using fuchsia::bluetooth::Status;

namespace gatt = fuchsia::bluetooth::gatt;

namespace bt_le_heart_rate {
namespace {

// See Heart Rate Service v1.0, 3.1.1.1 Flags Field
constexpr uint8_t kHeartRateValueFormat = 1 << 0;  // 1 for 16 bit rate value
constexpr uint8_t kSensorContactStatus = 1 << 1;
constexpr uint8_t kSensorContactSupported = 1 << 2;
constexpr uint8_t kEnergyExpendedStatus = 1 << 3;
constexpr uint8_t kRrInterval = 1 << 4;

// Convert an integer type to a smaller integer type with saturation.
template <typename To, typename From>
To Narrow(From value) {
  static_assert(sizeof(To) <= sizeof(From), "Can't narrow to a larger type");

  constexpr From lower_limit = std::numeric_limits<To>::min();
  static_assert(lower_limit >= std::numeric_limits<From>::min(), "Not 1:1");
  constexpr From upper_limit = std::numeric_limits<To>::max();
  static_assert(upper_limit <= std::numeric_limits<From>::max(), "Not 1:1");

  value = std::max(value, lower_limit);
  return static_cast<To>(std::min(value, upper_limit));
}

std::vector<uint8_t> MakeMeasurementPayload(int rate,
                                            const bool* sensor_contact,
                                            const int* energy_expended,
                                            const int* rr_interval) {
  std::vector<uint8_t> payload(1);

  // Compute width of field necessary for the heart rate.
  // Heart Rate Service v1.0, 3.1.1.1.1: "Heart Rate Value Format bit may change
  // during a connection."
  const uint8_t rate_8bit = Narrow<uint8_t>(rate);
  if (rate_8bit == rate) {
    payload.push_back(rate_8bit);
  } else {
    payload[0] |= kHeartRateValueFormat;
    const auto rate_16bit = Narrow<uint16_t>(rate);
    payload.push_back(static_cast<uint8_t>(rate_16bit));
    payload.push_back(static_cast<uint8_t>(rate_16bit >> 8));
  }

  if (sensor_contact) {
    payload[0] |= kSensorContactSupported;
    payload[0] |= *sensor_contact ? kSensorContactStatus : 0;
  }

  // Heart Rate Service v1.0, 3.1.1.3: "If the maximum value of 65535 kilo
  // Joules is attained (0xFFFF), the field value should remain at 0xFFFF."
  if (energy_expended) {
    payload[0] |= kEnergyExpendedStatus;
    const auto energy_expended_16bit = Narrow<uint16_t>(*energy_expended);
    payload.push_back(static_cast<uint8_t>(energy_expended_16bit));
    payload.push_back(static_cast<uint8_t>(energy_expended_16bit >> 8));
  }

  if (rr_interval) {
    payload[0] |= kRrInterval;
    const auto rr_interval_16bit = Narrow<uint16_t>(*rr_interval);
    payload.push_back(static_cast<uint8_t>(rr_interval_16bit));
    payload.push_back(static_cast<uint8_t>(rr_interval_16bit >> 8));
  }

  return payload;
}

void PrintBytes(const std::vector<uint8_t>& value) {
  const auto fmtflags = std::cout.flags();
  std::cout << std::hex;
  std::copy(value.begin(), value.end(),
            std::ostream_iterator<unsigned>(std::cout));
  std::cout.flags(fmtflags);
}

}  // namespace

constexpr char Service::kServiceUuid[];
constexpr uint64_t Service::kHeartRateMeasurementId;
constexpr char Service::kHeartRateMeasurementUuid[];
constexpr uint64_t Service::kBodySensorLocationId;
constexpr char Service::kBodySensorLocationUuid[];
constexpr uint64_t Service::kHeartRateControlPointId;
constexpr char Service::kHeartRateControlPointUuid[];

Service::Service(std::unique_ptr<HeartModel> heart_model)
    : heart_model_(std::move(heart_model)),
      binding_(this),
      notify_scheduled_(false),
      weak_factory_(this) {
  FXL_DCHECK(heart_model_);
}

void Service::PublishService(gatt::ServerPtr* gatt_server) {
  // Heart Rate Measurement
  // Allow update with default security of "none required."
  gatt::Characteristic hrm;
  hrm.id = kHeartRateMeasurementId;
  hrm.type = kHeartRateMeasurementUuid;
  hrm.properties = gatt::kPropertyNotify;
  hrm.permissions = gatt::AttributePermissions::New();
  hrm.permissions->update = gatt::SecurityRequirements::New();

  // Body Sensor Location
  gatt::Characteristic bsl;
  bsl.id = kBodySensorLocationId;
  bsl.type = kBodySensorLocationUuid;
  bsl.properties = gatt::kPropertyRead;
  bsl.permissions = gatt::AttributePermissions::New();
  bsl.permissions->read = gatt::SecurityRequirements::New();

  // Heart Rate Control Point
  gatt::Characteristic hrcp;
  hrcp.id = kHeartRateControlPointId;
  hrcp.type = kHeartRateControlPointUuid;
  hrcp.properties = gatt::kPropertyWrite;
  hrcp.permissions = gatt::AttributePermissions::New();
  hrcp.permissions->write = gatt::SecurityRequirements::New();

  fidl::VectorPtr<gatt::Characteristic> characteristics;
  characteristics.push_back(std::move(hrm));
  characteristics.push_back(std::move(bsl));
  characteristics.push_back(std::move(hrcp));

  gatt::ServiceInfo si;
  si.primary = true;
  si.type = kServiceUuid;
  si.characteristics = std::move(characteristics);

  std::cout << "Publishing service..." << std::endl;
  auto publish_svc_result_cb = [](Status status) {
    std::cout << "PublishService status: " << bool(status.error) << std::endl;
  };
  (*gatt_server)
      ->PublishService(std::move(si), binding_.NewBinding(),
                       service_.NewRequest(), std::move(publish_svc_result_cb));
}

void Service::NotifyMeasurement() {
  HeartModel::Measurement measurement = {};
  if (!heart_model_->ReadMeasurement(&measurement))
    return;

  const auto payload =
      MakeMeasurementPayload(measurement.rate, &measurement.contact,
                             &measurement.energy_expended, nullptr);

  for (const auto& peer_id : measurement_peers_) {
    service_->NotifyValue(0, peer_id,
                          fidl::VectorPtr<uint8_t>(std::move(payload)), false);
  }
}

void Service::ScheduleNotification() {
  auto self = weak_factory_.GetWeakPtr();
  async::PostDelayedTask(
      async_get_default_dispatcher(),
      [self] {
        if (!self)
          return;

        if (!self->measurement_peers_.empty()) {
          self->NotifyMeasurement();
          self->ScheduleNotification();
        } else {
          self->notify_scheduled_ = false;
        }
      },
      zx::msec(measurement_interval_));

  notify_scheduled_ = true;
}

void Service::OnCharacteristicConfiguration(uint64_t characteristic_id,
                                            std::string peer_id, bool notify,
                                            bool indicate) {
  std::cout << "CharacteristicConfiguration on peer " << peer_id
            << " (notify: " << notify << ", indicate: " << indicate << ")"
            << std::endl;

  if (characteristic_id != kHeartRateMeasurementId) {
    std::cout << "Ignoring configuration for characteristic other than Heart "
                 "Rate Measurement"
              << std::endl;
    return;
  }

  if (notify) {
    std::cout << "Enabling heart rate measurements for peer " << peer_id
              << std::endl;

    auto insert_res = measurement_peers_.insert(peer_id);
    if (insert_res.second && measurement_peers_.size() == 1) {
      if (!notify_scheduled_)
        ScheduleNotification();
    }
  } else {
    std::cout << "Disabling heart rate measurements for peer " << peer_id
              << std::endl;
    measurement_peers_.erase(peer_id);
  }
}

void Service::OnReadValue(uint64_t id, int32_t offset,
                          OnReadValueCallback callback) {
  std::cout << "ReadValue on characteristic " << id << " at offset " << offset
            << std::endl;

  if (id != kBodySensorLocationId) {
    callback(nullptr, gatt::ErrorCode::NOT_PERMITTED);
    return;
  }

  // Body Sensor Location payload
  fidl::VectorPtr<uint8_t> value;
  value.push_back(static_cast<uint8_t>(BodySensorLocation::kOther));
  callback(std::move(value), gatt::ErrorCode::NO_ERROR);
}

void Service::OnWriteValue(uint64_t id, uint16_t offset,
                           std::vector<uint8_t> value,
                           OnWriteValueCallback callback) {
  std::cout << "WriteValue on characteristic " << id << " at offset " << offset
            << " (";
  PrintBytes(value);
  std::cout << ")" << std::endl;

  if (id != kHeartRateControlPointId) {
    std::cout << "Ignoring writes to characteristic other than Heart Rate "
                 "Control Point"
              << std::endl;
    callback(gatt::ErrorCode::NOT_PERMITTED);
    return;
  }

  if (offset != 0) {
    std::cout << "Write to control point at invalid offset" << std::endl;
    callback(gatt::ErrorCode::INVALID_OFFSET);
    return;
  }

  if (value.size() != 1) {
    std::cout << "Write to control point of invalid length" << std::endl;
    callback(gatt::ErrorCode::INVALID_VALUE_LENGTH);
    return;
  }

  if (value[0] != kResetEnergyExpendedValue) {
    std::cout << "Write value other than \"Reset Energy Expended\" to "
                 "Heart Rate Control Point characteristic"
              << std::endl;
    callback(CONTROL_POINT_NOT_SUPPORTED);
    return;
  }

  std::cout << "Resetting Energy Expended" << std::endl;
  heart_model_->ResetEnergyExpended();
  callback(gatt::ErrorCode::NO_ERROR);
}

void Service::OnWriteWithoutResponse(uint64_t id, uint16_t offset,
                                     std::vector<uint8_t> value) {
  std::cout << "WriteWithoutResponse on characteristic " << id << " at offset "
            << offset << " (";
  PrintBytes(value);
  std::cout << ")" << std::endl;
}

}  // namespace bt_le_heart_rate
