// Copyright 2014 The Chromium 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 "chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h"

#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/rand_util.h"
#include "base/time/time.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

namespace chromeos {

namespace {

const int kStartNotifyResponseIntervalMs = 200;
const int kHeartRateMeasurementNotificationIntervalMs = 2000;

}  // namespace

FakeBluetoothGattCharacteristicClient::DelayedCallback::DelayedCallback(
    base::Closure callback,
    size_t delay)
    : callback_(callback), delay_(delay) {
}

FakeBluetoothGattCharacteristicClient::DelayedCallback::~DelayedCallback() {
}

// static
const char FakeBluetoothGattCharacteristicClient::
    kHeartRateMeasurementPathComponent[] = "char0000";
const char FakeBluetoothGattCharacteristicClient::
    kBodySensorLocationPathComponent[] = "char0001";
const char FakeBluetoothGattCharacteristicClient::
    kHeartRateControlPointPathComponent[] = "char0002";

// static
const char FakeBluetoothGattCharacteristicClient::kHeartRateMeasurementUUID[] =
    "00002a37-0000-1000-8000-00805f9b34fb";
const char FakeBluetoothGattCharacteristicClient::kBodySensorLocationUUID[] =
    "00002a38-0000-1000-8000-00805f9b34fb";
const char FakeBluetoothGattCharacteristicClient::kHeartRateControlPointUUID[] =
    "00002a39-0000-1000-8000-00805f9b34fb";

FakeBluetoothGattCharacteristicClient::Properties::Properties(
    const PropertyChangedCallback& callback)
    : BluetoothGattCharacteristicClient::Properties(
          NULL,
          bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface,
          callback) {
}

FakeBluetoothGattCharacteristicClient::Properties::~Properties() {
}

void FakeBluetoothGattCharacteristicClient::Properties::Get(
    dbus::PropertyBase* property,
    dbus::PropertySet::GetCallback callback) {
  VLOG(1) << "Get " << property->name();
  callback.Run(true);
}

void FakeBluetoothGattCharacteristicClient::Properties::GetAll() {
  VLOG(1) << "GetAll";
}

void FakeBluetoothGattCharacteristicClient::Properties::Set(
    dbus::PropertyBase* property,
    dbus::PropertySet::SetCallback callback) {
  VLOG(1) << "Set " << property->name();
  callback.Run(false);
}

FakeBluetoothGattCharacteristicClient::FakeBluetoothGattCharacteristicClient()
    : heart_rate_visible_(false),
      authorized_(true),
      authenticated_(true),
      calories_burned_(0),
      extra_requests_(0),
      weak_ptr_factory_(this) {
}

FakeBluetoothGattCharacteristicClient::
    ~FakeBluetoothGattCharacteristicClient() {
  for (const auto& it : action_extra_requests_) {
    delete it.second;
  }
  action_extra_requests_.clear();
}

void FakeBluetoothGattCharacteristicClient::Init(dbus::Bus* bus) {
}

void FakeBluetoothGattCharacteristicClient::AddObserver(Observer* observer) {
  observers_.AddObserver(observer);
}

void FakeBluetoothGattCharacteristicClient::RemoveObserver(Observer* observer) {
  observers_.RemoveObserver(observer);
}

std::vector<dbus::ObjectPath>
FakeBluetoothGattCharacteristicClient::GetCharacteristics() {
  std::vector<dbus::ObjectPath> paths;
  if (IsHeartRateVisible()) {
    paths.push_back(dbus::ObjectPath(heart_rate_measurement_path_));
    paths.push_back(dbus::ObjectPath(body_sensor_location_path_));
    paths.push_back(dbus::ObjectPath(heart_rate_control_point_path_));
  }
  return paths;
}

FakeBluetoothGattCharacteristicClient::Properties*
FakeBluetoothGattCharacteristicClient::GetProperties(
    const dbus::ObjectPath& object_path) {
  if (object_path.value() == heart_rate_measurement_path_) {
    DCHECK(heart_rate_measurement_properties_.get());
    return heart_rate_measurement_properties_.get();
  }
  if (object_path.value() == body_sensor_location_path_) {
    DCHECK(body_sensor_location_properties_.get());
    return body_sensor_location_properties_.get();
  }
  if (object_path.value() == heart_rate_control_point_path_) {
    DCHECK(heart_rate_control_point_properties_.get());
    return heart_rate_control_point_properties_.get();
  }
  return NULL;
}

void FakeBluetoothGattCharacteristicClient::ReadValue(
    const dbus::ObjectPath& object_path,
    const ValueCallback& callback,
    const ErrorCallback& error_callback) {
  if (!authenticated_) {
    error_callback.Run("org.bluez.Error.NotPaired", "Please login");
    return;
  }

  if (!authorized_) {
    error_callback.Run("org.bluez.Error.NotAuthorized", "Authorize first");
    return;
  }

  if (object_path.value() == heart_rate_control_point_path_) {
    error_callback.Run("org.bluez.Error.ReadNotPermitted",
                       "Reads of this value are not allowed");
    return;
  }

  if (object_path.value() == heart_rate_measurement_path_) {
    error_callback.Run("org.bluez.Error.NotSupported",
                       "Action not supported on this characteristic");
    return;
  }

  if (object_path.value() != body_sensor_location_path_) {
    error_callback.Run(kUnknownCharacteristicError, "");
    return;
  }

  if (action_extra_requests_.find("ReadValue") !=
      action_extra_requests_.end()) {
    DelayedCallback* delayed = action_extra_requests_["ReadValue"];
    delayed->delay_--;
    error_callback.Run("org.bluez.Error.InProgress",
                       "Another read is currenty in progress");
    if (delayed->delay_ == 0) {
      delayed->callback_.Run();
      action_extra_requests_.erase("ReadValue");
      delete delayed;
    }
    return;
  }
  base::Closure completed_callback;
  if (!IsHeartRateVisible()) {
    completed_callback =
        base::Bind(error_callback, kUnknownCharacteristicError, "");
  } else {
    std::vector<uint8> value;
    value.push_back(0x06);  // Location is "foot".
    completed_callback = base::Bind(callback, value);
  }

  if (extra_requests_ > 0) {
    action_extra_requests_["ReadValue"] =
        new DelayedCallback(completed_callback, extra_requests_);
    return;
  }
  completed_callback.Run();
}

void FakeBluetoothGattCharacteristicClient::WriteValue(
    const dbus::ObjectPath& object_path,
    const std::vector<uint8>& value,
    const base::Closure& callback,
    const ErrorCallback& error_callback) {
  if (!authenticated_) {
    error_callback.Run("org.bluez.Error.NotPaired", "Please login");
    return;
  }

  if (!authorized_) {
    error_callback.Run("org.bluez.Error.NotAuthorized", "Authorize first");
    return;
  }

  if (!IsHeartRateVisible()) {
    error_callback.Run(kUnknownCharacteristicError, "");
    return;
  }

  if (object_path.value() == heart_rate_measurement_path_) {
    error_callback.Run("org.bluez.Error.NotSupported",
                       "Action not supported on this characteristic");
    return;
  }

  if (object_path.value() != heart_rate_control_point_path_) {
    error_callback.Run("org.bluez.Error.WriteNotPermitted",
                       "Writes of this value are not allowed");
    return;
  }

  DCHECK(heart_rate_control_point_properties_.get());
  if (action_extra_requests_.find("WriteValue") !=
      action_extra_requests_.end()) {
    DelayedCallback* delayed = action_extra_requests_["WriteValue"];
    delayed->delay_--;
    error_callback.Run("org.bluez.Error.InProgress",
                       "Another write is in progress");
    if (delayed->delay_ == 0) {
      delayed->callback_.Run();
      action_extra_requests_.erase("WriteValue");
      delete delayed;
    }
    return;
  }
  base::Closure completed_callback;
  if (value.size() != 1) {
    completed_callback = base::Bind(error_callback,
                                    "org.bluez.Error.InvalidValueLength",
                                    "Invalid length for write");
  } else if (value[0] > 1) {
    completed_callback = base::Bind(error_callback,
                                    "org.bluez.Error.Failed",
                                    "Invalid value given for write");
  } else if (value[0] == 1) {
    // TODO(jamuraa): make this happen when the callback happens
    calories_burned_ = 0;
    completed_callback = callback;
  }

  if (extra_requests_ > 0) {
    action_extra_requests_["WriteValue"] =
        new DelayedCallback(completed_callback, extra_requests_);
    return;
  }
  completed_callback.Run();
}

void FakeBluetoothGattCharacteristicClient::StartNotify(
    const dbus::ObjectPath& object_path,
    const base::Closure& callback,
    const ErrorCallback& error_callback) {
  if (!IsHeartRateVisible()) {
    error_callback.Run(kUnknownCharacteristicError, "");
    return;
  }

  if (object_path.value() != heart_rate_measurement_path_) {
    error_callback.Run("org.bluez.Error.NotSupported",
                       "This characteristic does not support notifications");
    return;
  }

  if (heart_rate_measurement_properties_->notifying.value()) {
    error_callback.Run("org.bluez.Error.InProgress",
                       "Characteristic already notifying");
    return;
  }

  heart_rate_measurement_properties_->notifying.ReplaceValue(true);
  ScheduleHeartRateMeasurementValueChange();

  // Respond asynchronously.
  base::MessageLoop::current()->PostDelayedTask(
      FROM_HERE,
      callback,
      base::TimeDelta::FromMilliseconds(kStartNotifyResponseIntervalMs));
}

void FakeBluetoothGattCharacteristicClient::StopNotify(
    const dbus::ObjectPath& object_path,
    const base::Closure& callback,
    const ErrorCallback& error_callback) {
  if (!IsHeartRateVisible()) {
    error_callback.Run(kUnknownCharacteristicError, "");
    return;
  }

  if (object_path.value() != heart_rate_measurement_path_) {
    error_callback.Run("org.bluez.Error.NotSupported",
                       "This characteristic does not support notifications");
    return;
  }

  if (!heart_rate_measurement_properties_->notifying.value()) {
    error_callback.Run("org.bluez.Error.Failed", "Not notifying");
    return;
  }

  heart_rate_measurement_properties_->notifying.ReplaceValue(false);

  callback.Run();
}

void FakeBluetoothGattCharacteristicClient::ExposeHeartRateCharacteristics(
    const dbus::ObjectPath& service_path) {
  if (IsHeartRateVisible()) {
    VLOG(2) << "Fake Heart Rate characteristics are already visible.";
    return;
  }

  VLOG(2) << "Exposing fake Heart Rate characteristics.";

  std::vector<std::string> flags;

  // ==== Heart Rate Measurement Characteristic ====
  heart_rate_measurement_path_ =
      service_path.value() + "/" + kHeartRateMeasurementPathComponent;
  heart_rate_measurement_properties_.reset(new Properties(base::Bind(
      &FakeBluetoothGattCharacteristicClient::OnPropertyChanged,
      weak_ptr_factory_.GetWeakPtr(),
      dbus::ObjectPath(heart_rate_measurement_path_))));
  heart_rate_measurement_properties_->uuid.ReplaceValue(
      kHeartRateMeasurementUUID);
  heart_rate_measurement_properties_->service.ReplaceValue(service_path);
  flags.push_back(bluetooth_gatt_characteristic::kFlagNotify);
  heart_rate_measurement_properties_->flags.ReplaceValue(flags);

  // ==== Body Sensor Location Characteristic ====
  body_sensor_location_path_ =
      service_path.value() + "/" + kBodySensorLocationPathComponent;
  body_sensor_location_properties_.reset(new Properties(base::Bind(
      &FakeBluetoothGattCharacteristicClient::OnPropertyChanged,
      weak_ptr_factory_.GetWeakPtr(),
      dbus::ObjectPath(body_sensor_location_path_))));
  body_sensor_location_properties_->uuid.ReplaceValue(kBodySensorLocationUUID);
  body_sensor_location_properties_->service.ReplaceValue(service_path);
  flags.clear();
  flags.push_back(bluetooth_gatt_characteristic::kFlagRead);
  body_sensor_location_properties_->flags.ReplaceValue(flags);

  // ==== Heart Rate Control Point Characteristic ====
  heart_rate_control_point_path_ =
      service_path.value() + "/" + kHeartRateControlPointPathComponent;
  heart_rate_control_point_properties_.reset(new Properties(base::Bind(
      &FakeBluetoothGattCharacteristicClient::OnPropertyChanged,
      weak_ptr_factory_.GetWeakPtr(),
      dbus::ObjectPath(heart_rate_control_point_path_))));
  heart_rate_control_point_properties_->uuid.ReplaceValue(
      kHeartRateControlPointUUID);
  heart_rate_control_point_properties_->service.ReplaceValue(service_path);
  flags.clear();
  flags.push_back(bluetooth_gatt_characteristic::kFlagWrite);
  heart_rate_control_point_properties_->flags.ReplaceValue(flags);

  heart_rate_visible_ = true;

  NotifyCharacteristicAdded(dbus::ObjectPath(heart_rate_measurement_path_));
  NotifyCharacteristicAdded(dbus::ObjectPath(body_sensor_location_path_));
  NotifyCharacteristicAdded(dbus::ObjectPath(heart_rate_control_point_path_));

  // Expose CCC descriptor for Heart Rate Measurement characteristic.
  FakeBluetoothGattDescriptorClient* descriptor_client =
      static_cast<FakeBluetoothGattDescriptorClient*>(
          DBusThreadManager::Get()->GetBluetoothGattDescriptorClient());
  dbus::ObjectPath ccc_path(descriptor_client->ExposeDescriptor(
      dbus::ObjectPath(heart_rate_measurement_path_),
      FakeBluetoothGattDescriptorClient::
          kClientCharacteristicConfigurationUUID));
  DCHECK(ccc_path.IsValid());
  heart_rate_measurement_ccc_desc_path_ = ccc_path.value();

  std::vector<dbus::ObjectPath> desc_paths;
  desc_paths.push_back(ccc_path);

  heart_rate_measurement_properties_->descriptors.ReplaceValue(desc_paths);
}

void FakeBluetoothGattCharacteristicClient::HideHeartRateCharacteristics() {
  VLOG(2) << "Hiding fake Heart Rate characteristics.";

  // Hide the descriptors.
  FakeBluetoothGattDescriptorClient* descriptor_client =
      static_cast<FakeBluetoothGattDescriptorClient*>(
          DBusThreadManager::Get()->GetBluetoothGattDescriptorClient());
  descriptor_client->HideDescriptor(
      dbus::ObjectPath(heart_rate_measurement_ccc_desc_path_));

  // Notify the observers before deleting the properties structures so that they
  // can be accessed from the observer method.
  NotifyCharacteristicRemoved(dbus::ObjectPath(heart_rate_measurement_path_));
  NotifyCharacteristicRemoved(dbus::ObjectPath(body_sensor_location_path_));
  NotifyCharacteristicRemoved(dbus::ObjectPath(heart_rate_control_point_path_));

  heart_rate_measurement_properties_.reset();
  body_sensor_location_properties_.reset();
  heart_rate_control_point_properties_.reset();

  heart_rate_measurement_path_.clear();
  body_sensor_location_path_.clear();
  heart_rate_control_point_path_.clear();
  heart_rate_visible_ = false;
}

void FakeBluetoothGattCharacteristicClient::SetExtraProcessing(
    size_t requests) {
  extra_requests_ = requests;
  if (extra_requests_ == 0) {
    for (const auto& it : action_extra_requests_) {
      it.second->callback_.Run();
      delete it.second;
    }
    action_extra_requests_.clear();
    return;
  }
  VLOG(2) << "Requests SLOW now, " << requests << " InProgress errors each.";
}

size_t FakeBluetoothGattCharacteristicClient::GetExtraProcessing() const {
  return extra_requests_;
}

dbus::ObjectPath
FakeBluetoothGattCharacteristicClient::GetHeartRateMeasurementPath() const {
  return dbus::ObjectPath(heart_rate_measurement_path_);
}

dbus::ObjectPath
FakeBluetoothGattCharacteristicClient::GetBodySensorLocationPath() const {
  return dbus::ObjectPath(body_sensor_location_path_);
}

dbus::ObjectPath
FakeBluetoothGattCharacteristicClient::GetHeartRateControlPointPath() const {
  return dbus::ObjectPath(heart_rate_control_point_path_);
}

void FakeBluetoothGattCharacteristicClient::OnPropertyChanged(
    const dbus::ObjectPath& object_path,
    const std::string& property_name) {
  VLOG(2) << "Characteristic property changed: " << object_path.value()
          << ": " << property_name;

  FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer, observers_,
                    GattCharacteristicPropertyChanged(
                        object_path, property_name));
}

void FakeBluetoothGattCharacteristicClient::NotifyCharacteristicAdded(
    const dbus::ObjectPath& object_path) {
  VLOG(2) << "GATT characteristic added: " << object_path.value();
  FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer, observers_,
                    GattCharacteristicAdded(object_path));
}

void FakeBluetoothGattCharacteristicClient::NotifyCharacteristicRemoved(
    const dbus::ObjectPath& object_path) {
  VLOG(2) << "GATT characteristic removed: " << object_path.value();
  FOR_EACH_OBSERVER(BluetoothGattCharacteristicClient::Observer, observers_,
                    GattCharacteristicRemoved(object_path));
}

void FakeBluetoothGattCharacteristicClient::
    ScheduleHeartRateMeasurementValueChange() {
  if (!IsHeartRateVisible())
    return;

  // Don't send updates if the characteristic is not notifying.
  if (!heart_rate_measurement_properties_->notifying.value())
    return;

  VLOG(2) << "Updating heart rate value.";
  std::vector<uint8> measurement = GetHeartRateMeasurementValue();

  FOR_EACH_OBSERVER(
      BluetoothGattCharacteristicClient::Observer,
      observers_,
      GattCharacteristicValueUpdated(
          dbus::ObjectPath(heart_rate_measurement_path_), measurement));

  base::MessageLoop::current()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&FakeBluetoothGattCharacteristicClient::
                     ScheduleHeartRateMeasurementValueChange,
                 weak_ptr_factory_.GetWeakPtr()),
                 base::TimeDelta::FromMilliseconds(
                     kHeartRateMeasurementNotificationIntervalMs));
}

std::vector<uint8>
FakeBluetoothGattCharacteristicClient::GetHeartRateMeasurementValue() {
  // TODO(armansito): We should make sure to properly pack this struct to ensure
  // correct byte alignment and endianness. It doesn't matter too much right now
  // as this is a fake and GCC on Linux seems to do the right thing.
  struct {
    uint8 flags;
    uint8 bpm;
    uint16 energy_expanded;
    uint16 rr_interval;
  } value;

  // Flags in LSB:     0       11   1 1 000
  //                   |       |    | | |
  // 8-bit bpm format --       |    | | |
  // Sensor contact supported --    | | |
  // Energy expanded field present -- | |
  // RR-Interval values present ------- |
  // Reserved for future use ------------
  value.flags = 0x0;
  value.flags |= (0x03 << 1);
  value.flags |= (0x01 << 3);
  value.flags |= (0x01 << 4);

  // Pick a value between 117 bpm and 153 bpm for heart rate.
  value.bpm = static_cast<uint8>(base::RandInt(117, 153));

  // Total calories burned in kJoules since the last reset. Increment this by 1
  // every time. It's fine if it overflows: it becomes 0 when the user resets
  // the heart rate monitor (or pretend that he had a lot of cheeseburgers).
  value.energy_expanded = calories_burned_++;

  // Include one RR-Interval value, in seconds.
  value.rr_interval = 60/value.bpm;

  // Return the bytes in an array.
  uint8* bytes = reinterpret_cast<uint8*>(&value);
  std::vector<uint8> return_value;
  return_value.assign(bytes, bytes + sizeof(value));
  return return_value;
}

bool FakeBluetoothGattCharacteristicClient::IsHeartRateVisible() const {
  DCHECK(heart_rate_visible_ != heart_rate_measurement_path_.empty());
  DCHECK(heart_rate_visible_ != body_sensor_location_path_.empty());
  DCHECK(heart_rate_visible_ != heart_rate_control_point_path_.empty());
  DCHECK(heart_rate_visible_ == !!heart_rate_measurement_properties_.get());
  DCHECK(heart_rate_visible_ == !!body_sensor_location_properties_.get());
  DCHECK(heart_rate_visible_ == !!heart_rate_control_point_properties_.get());
  return heart_rate_visible_;
}

}  // namespace chromeos
