//
//  Copyright (C) 2015 Google, Inc.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at:
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//

#include "service/example/heart_rate/heart_rate_server.h"

#include <base/bind.h>
#include <base/location.h>
#include <base/logging.h>
#include <base/rand_util.h>

#include <android/bluetooth/BnBluetoothLowEnergyCallback.h>
#include <android/bluetooth/IBluetoothLowEnergy.h>
#include <bluetooth/low_energy_constants.h>

#include "service/example/heart_rate/constants.h"

using android::binder::Status;
using android::String8;
using android::String16;

using android::bluetooth::IBluetoothLowEnergy;

namespace heart_rate {

class CLIBluetoothLowEnergyCallback
    : public android::bluetooth::BnBluetoothLowEnergyCallback {
 public:
  explicit CLIBluetoothLowEnergyCallback(android::sp<android::bluetooth::IBluetooth> bt)
      : bt_(bt) {}

  // IBluetoothLowEnergyCallback overrides:
  Status OnConnectionState(int status, int client_id, const String16& address,
                           bool connected) override {
    return Status::ok();
  }

  Status OnMtuChanged(int status, const String16& address, int mtu) override {
    return Status::ok();
  }

  Status OnScanResult(
      const android::bluetooth::ScanResult& scan_result) override {
    return Status::ok();
  }

  Status OnClientRegistered(int status, int client_id) {
    if (status != bluetooth::BLE_STATUS_SUCCESS) {
      LOG(ERROR) << "Failed to register BLE client, will not start advertising";
      return Status::ok();
    }

    LOG(INFO) << "Registered BLE client with ID: " << client_id;

    /* Advertising data: 16-bit Service UUID: Heart Rate Service */
    std::vector<uint8_t> data{0x03, 0x03, 0x0D, 0x18};
    base::TimeDelta timeout;

    bluetooth::AdvertiseSettings settings(
        bluetooth::AdvertiseSettings::MODE_LOW_POWER, timeout,
        bluetooth::AdvertiseSettings::TX_POWER_LEVEL_MEDIUM, true);

    bluetooth::AdvertiseData adv_data(data);
    adv_data.set_include_device_name(true);
    adv_data.set_include_tx_power_level(true);

    bluetooth::AdvertiseData scan_rsp;

    android::sp<IBluetoothLowEnergy> ble;
    bt_->GetLowEnergyInterface(&ble);
    bool start_status;
    ble->StartMultiAdvertising(client_id, adv_data, scan_rsp, settings,
                               &start_status);
    return Status::ok();
  }

  Status OnMultiAdvertiseCallback(
      int status, bool is_start,
      const android::bluetooth::AdvertiseSettings& /* settings */) {
    LOG(INFO) << "Advertising" << (is_start ? " started" : " stopped");
    return Status::ok();
  };

 private:
  android::sp<android::bluetooth::IBluetooth> bt_;
  DISALLOW_COPY_AND_ASSIGN(CLIBluetoothLowEnergyCallback);
};

HeartRateServer::HeartRateServer(
    android::sp<android::bluetooth::IBluetooth> bluetooth,
    scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
    bool advertise)
    : simulation_started_(false),
      bluetooth_(bluetooth),
      server_if_(-1),
      hr_notification_count_(0),
      energy_expended_(0),
      advertise_(advertise),
      main_task_runner_(main_task_runner),
      weak_ptr_factory_(this) {
  CHECK(bluetooth_.get());
}

HeartRateServer::~HeartRateServer() {
  std::lock_guard<std::mutex> lock(mutex_);
  if (!gatt_.get() || server_if_ == -1) return;

  if (!android::IInterface::asBinder(gatt_.get())->isBinderAlive()) return;

  // Manually unregister ourselves from the daemon. It's good practice to do
  // this, even though the daemon will automatically unregister us if this
  // process exits.
  gatt_->UnregisterServer(server_if_);
}

bool HeartRateServer::Run(const RunCallback& callback) {
  std::lock_guard<std::mutex> lock(mutex_);

  if (pending_run_cb_) {
    LOG(ERROR) << "Already started";
    return false;
  }

  // Grab the IBluetoothGattServer binder from the Bluetooth daemon.
  bluetooth_->GetGattServerInterface(&gatt_);
  if (!gatt_.get()) {
    LOG(ERROR) << "Failed to obtain handle to IBluetoothGattServer interface";
    return false;
  }

  // Register this instance as a GATT server. If this call succeeds, we will
  // asynchronously receive a server ID via the OnServerRegistered callback.
  bool status;
  gatt_->RegisterServer(this, &status);
  if (!status) {
    LOG(ERROR) << "Failed to register with the server interface";
    return false;
  }

  pending_run_cb_ = callback;

  return true;
}

void HeartRateServer::ScheduleNextMeasurement() {
  main_task_runner_->PostDelayedTask(
      FROM_HERE, base::Bind(&HeartRateServer::SendHeartRateMeasurement,
                            weak_ptr_factory_.GetWeakPtr()),
      base::TimeDelta::FromSeconds(1));
}

void HeartRateServer::SendHeartRateMeasurement() {
  std::lock_guard<std::mutex> lock(mutex_);

  // Send a notification or indication to all enabled devices.
  bool found = false;
  for (const auto& iter : device_ccc_map_) {
    uint8_t ccc_val = iter.second;

    if (!ccc_val) continue;

    found = true;

    // Don't send a notification if one is already pending for this device.
    if (pending_notification_map_[iter.first]) continue;

    std::vector<uint8_t> value;
    BuildHeartRateMeasurementValue(&value);

    bool status;
    gatt_->SendNotification(server_if_, String16(String8(iter.first.c_str())),
                            hr_measurement_id_, false, value, &status);
    if (status) pending_notification_map_[iter.first] = true;
  }

  // Still enabled!
  if (found) {
    ScheduleNextMeasurement();
    return;
  }

  // All clients disabled notifications.
  simulation_started_ = false;

  // TODO(armansito): We should keep track of closed connections here so that we
  // don't send notifications to uninterested clients.
}

void HeartRateServer::BuildHeartRateMeasurementValue(
    std::vector<uint8_t>* out_value) {
  CHECK(out_value);  // Assert that |out_value| is not nullptr.

  // Default flags field. Here is what we put in there:
  //   Bit 0: 0 - 8-bit Heart Rate value
  //   Bits 1 & 2: 11 - Sensor contact feature supported and contact detected.
  uint8_t flags = kHRValueFormat8Bit | kHRSensorContactDetected;

  // Our demo's heart rate. Pick a value between 90 and 130.
  uint8_t heart_rate = base::RandInt(90, 130);

  // On every tenth beat we include the Energy Expended value.
  bool include_ee = false;
  if (!(hr_notification_count_ % 10)) {
    include_ee = true;
    flags |= kHREnergyExpendedPresent;
  }

  hr_notification_count_++;
  energy_expended_ = std::min(UINT16_MAX, (int)energy_expended_ + 1);

  // Add all the value bytes.
  out_value->push_back(flags);
  out_value->push_back(heart_rate);
  if (include_ee) {
    out_value->push_back(energy_expended_);
    out_value->push_back(energy_expended_ >> 8);
  }
}

Status HeartRateServer::OnServerRegistered(int status, int server_if) {
  std::lock_guard<std::mutex> lock(mutex_);

  if (status != bluetooth::BLE_STATUS_SUCCESS) {
    LOG(ERROR) << "Failed to register GATT server";
    pending_run_cb_(false);
    return Status::ok();
  }

  // Registration succeeded. Store our ID, as we need it for GATT server
  // operations.
  server_if_ = server_if;

  LOG(INFO) << "Heart Rate server registered - server_if: " << server_if_;
  LOG(INFO) << "Populating attributes";

  bool op_status;
  // Start service declaration.
  android::bluetooth::GattIdentifier gatt_id;
  gatt_->BeginServiceDeclaration(server_if_, true, kHRServiceUUID, &gatt_id,
                                 &op_status);
  if (!op_status) {
    LOG(ERROR) << "Failed to begin service declaration";
    pending_run_cb_(false);
    return Status::ok();
  }

  hr_service_id_ = gatt_id;

  // Add Heart Rate Measurement characteristic.
  gatt_->AddCharacteristic(server_if_, kHRMeasurementUUID,
                           bluetooth::kCharacteristicPropertyNotify, 0,
                           &gatt_id, &op_status);
  if (!op_status) {
    LOG(ERROR) << "Failed to add heart rate measurement characteristic";
    pending_run_cb_(false);
    return Status::ok();
  }

  hr_measurement_id_ = gatt_id;

  // Add Client Characteristic Configuration descriptor for the Heart Rate
  // Measurement characteristic.
  gatt_->AddDescriptor(server_if_, kCCCDescriptorUUID,
                       bluetooth::kAttributePermissionRead |
                           bluetooth::kAttributePermissionWrite,
                       &gatt_id, &op_status);
  if (!op_status) {
    LOG(ERROR) << "Failed to add CCC descriptor";
    pending_run_cb_(false);
    return Status::ok();
  }

  hr_measurement_cccd_id_ = gatt_id;

  // Add Body Sensor Location characteristic.
  gatt_->AddCharacteristic(server_if_, kBodySensorLocationUUID,
                           bluetooth::kCharacteristicPropertyRead,
                           bluetooth::kAttributePermissionRead, &gatt_id,
                           &op_status);
  if (!op_status) {
    LOG(ERROR) << "Failed to add body sensor location characteristic";
    pending_run_cb_(false);
    return Status::ok();
  }

  body_sensor_loc_id_ = gatt_id;

  // Add Heart Rate Control Point characteristic.
  gatt_->AddCharacteristic(
      server_if_, kHRControlPointUUID, bluetooth::kCharacteristicPropertyWrite,
      bluetooth::kAttributePermissionWrite, &gatt_id, &op_status);
  if (!op_status) {
    LOG(ERROR) << "Failed to add heart rate control point characteristic";
    pending_run_cb_(false);
    return Status::ok();
  }

  hr_control_point_id_ = gatt_id;

  // End service declaration. We will be notified whether or not this succeeded
  // via the OnServiceAdded callback.
  gatt_->EndServiceDeclaration(server_if_, &op_status);
  if (!op_status) {
    LOG(ERROR) << "Failed to end service declaration";
    pending_run_cb_(false);
    return Status::ok();
  }

  LOG(INFO) << "Initiated EndServiceDeclaration request";
  return Status::ok();
}

Status HeartRateServer::OnServiceAdded(
    int status, const android::bluetooth::GattIdentifier& service_id) {
  std::lock_guard<std::mutex> lock(mutex_);

  if (status != bluetooth::BLE_STATUS_SUCCESS) {
    LOG(ERROR) << "Failed to add Heart Rate service";
    pending_run_cb_(false);
    return Status::ok();
  }

  if (service_id != hr_service_id_) {
    LOG(ERROR) << "Received callback for the wrong service ID";
    pending_run_cb_(false);
    return Status::ok();
  }

  // EndServiceDeclaration succeeded! Our Heart Rate service is now discoverable
  // over GATT connections.

  LOG(INFO) << "Heart Rate service added";
  pending_run_cb_(true);

  if (advertise_) {
    android::sp<IBluetoothLowEnergy> ble;
    bluetooth_->GetLowEnergyInterface(&ble);
    bool status;
    ble->RegisterClient(new CLIBluetoothLowEnergyCallback(bluetooth_), &status);
  }

  return Status::ok();
}

Status HeartRateServer::OnCharacteristicReadRequest(
    const String16& device_address, int request_id, int offset,
    bool /* is_long */,
    const android::bluetooth::GattIdentifier& characteristic_id) {
  std::lock_guard<std::mutex> lock(mutex_);

  // This is where we handle an incoming characteristic read. Only the body
  // sensor location characteristic is readable.
  CHECK(characteristic_id == body_sensor_loc_id_);

  std::vector<uint8_t> value;
  bluetooth::GATTError error = bluetooth::GATT_ERROR_NONE;
  if (offset > 1)
    error = bluetooth::GATT_ERROR_INVALID_OFFSET;
  else if (offset == 0)
    value.push_back(kHRBodyLocationFoot);

  bool status;
  gatt_->SendResponse(server_if_, device_address, request_id, error, offset,
                      value, &status);
  return Status::ok();
}

Status HeartRateServer::OnDescriptorReadRequest(
    const String16& device_address, int request_id, int offset,
    bool /* is_long */,
    const android::bluetooth::GattIdentifier& descriptor_id) {
  std::lock_guard<std::mutex> lock(mutex_);

  // This is where we handle an incoming characteristic descriptor read. There
  // is only one descriptor.
  if (descriptor_id != hr_measurement_cccd_id_) {
    std::vector<uint8_t> value;
    bool status;
    gatt_->SendResponse(server_if_, device_address, request_id,
                        bluetooth::GATT_ERROR_ATTRIBUTE_NOT_FOUND, offset,
                        value, &status);
    return Status::ok();
  }

  // 16-bit value encoded as little-endian.
  const uint8_t value_bytes[] = {
      device_ccc_map_[std::string(String8(device_address).string())], 0x00};

  std::vector<uint8_t> value;
  bluetooth::GATTError error = bluetooth::GATT_ERROR_NONE;
  if (offset > 2)
    error = bluetooth::GATT_ERROR_INVALID_OFFSET;
  else
    value.insert(value.begin(), value_bytes + offset, value_bytes + 2 - offset);

  bool status;
  gatt_->SendResponse(server_if_, device_address, request_id, error, offset,
                      value, &status);
  return Status::ok();
}

Status HeartRateServer::OnCharacteristicWriteRequest(
    const String16& device_address, int request_id, int offset,
    bool is_prepare_write, bool need_response,
    const std::vector<uint8_t>& value,
    const android::bluetooth::GattIdentifier& characteristic_id) {
  std::lock_guard<std::mutex> lock(mutex_);

  std::vector<uint8_t> dummy;

  // This is where we handle an incoming characteristic write. The Heart Rate
  // service doesn't really support prepared writes, so we just reject them to
  // keep things simple.
  if (is_prepare_write) {
    bool status;
    gatt_->SendResponse(server_if_, device_address, request_id,
                        bluetooth::GATT_ERROR_REQUEST_NOT_SUPPORTED, offset,
                        dummy, &status);
    return Status::ok();
  }

  // Heart Rate Control point is the only writable characteristic.
  CHECK(characteristic_id == hr_control_point_id_);

  // Writes to the Heart Rate Control Point characteristic must contain a single
  // byte with the value 0x01.
  if (value.size() != 1 || value[0] != 0x01) {
    bool status;
    gatt_->SendResponse(server_if_, device_address, request_id,
                        bluetooth::GATT_ERROR_OUT_OF_RANGE, offset, dummy,
                        &status);
    return Status::ok();
  }

  LOG(INFO) << "Heart Rate Control Point written; Enery Expended reset!";
  energy_expended_ = 0;

  if (!need_response) return Status::ok();

  bool status;
  gatt_->SendResponse(server_if_, device_address, request_id,
                      bluetooth::GATT_ERROR_NONE, offset, dummy, &status);
  return Status::ok();
}

Status HeartRateServer::OnDescriptorWriteRequest(
    const String16& device_address, int request_id, int offset,
    bool is_prepare_write, bool need_response,
    const std::vector<uint8_t>& value,
    const android::bluetooth::GattIdentifier& descriptor_id) {
  std::lock_guard<std::mutex> lock(mutex_);

  std::vector<uint8_t> dummy;

  // This is where we handle an incoming characteristic write. The Heart Rate
  // service doesn't really support prepared writes, so we just reject them to
  // keep things simple.
  if (is_prepare_write) {
    bool status;
    gatt_->SendResponse(server_if_, device_address, request_id,
                        bluetooth::GATT_ERROR_REQUEST_NOT_SUPPORTED, offset,
                        dummy, &status);
    return Status::ok();
  }

  // CCC is the only descriptor we have.
  CHECK(descriptor_id == hr_measurement_cccd_id_);

  // CCC must contain 2 bytes for a 16-bit value in little-endian. The only
  // allowed values here are 0x0000 and 0x0001.
  if (value.size() != 2 || value[1] != 0x00 || value[0] > 0x01) {
    bool status;
    gatt_->SendResponse(server_if_, device_address, request_id,
                        bluetooth::GATT_ERROR_CCCD_IMPROPERLY_CONFIGURED,
                        offset, dummy, &status);
    return Status::ok();
  }

  device_ccc_map_[std::string(String8(device_address).string())] = value[0];

  LOG(INFO) << "Heart Rate Measurement CCC written - device: " << device_address
            << " value: " << (int)value[0];

  // Start the simulation.
  if (!simulation_started_ && value[0]) {
    simulation_started_ = true;
    ScheduleNextMeasurement();
  }

  if (!need_response) return Status::ok();

  bool status;
  gatt_->SendResponse(server_if_, device_address, request_id,
                      bluetooth::GATT_ERROR_NONE, offset, dummy, &status);
  return Status::ok();
}

Status HeartRateServer::OnExecuteWriteRequest(const String16& device_address,
                                              int request_id,
                                              bool /* is_execute */) {
  // We don't support Prepared Writes so, simply return Not Supported error.
  std::vector<uint8_t> dummy;
  bool status;
  gatt_->SendResponse(server_if_, device_address, request_id,
                      bluetooth::GATT_ERROR_REQUEST_NOT_SUPPORTED, 0, dummy,
                      &status);

  return Status::ok();
}

Status HeartRateServer::OnNotificationSent(const String16& device_address,
                                           int status) {
  LOG(INFO) << "Notification was sent - device: " << device_address
            << " status: " << status;
  std::lock_guard<std::mutex> lock(mutex_);
  pending_notification_map_[std::string(String8(device_address).string())] =
      false;

  return Status::ok();
}

}  // namespace heart_rate
