// Copyright 2017 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 "device/bluetooth/bluetooth_remote_gatt_descriptor_mac.h"

#include "base/bind.h"
#import "base/mac/foundation_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#import "device/bluetooth/bluetooth_adapter_mac.h"
#include "device/bluetooth/bluetooth_adapter_mac_metrics.h"
#import "device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h"

using base::mac::ObjCCast;

namespace device {

std::vector<uint8_t> VectorValueFromObjC(id objc_value) {
  // According to
  // https://developer.apple.com/reference/corebluetooth/cbdescriptor some
  // descriptor values can be NSData, NSString or NSNumber.
  std::vector<uint8_t> value;
  NSData* data = ObjCCast<NSData>(objc_value);
  NSString* as_string = ObjCCast<NSString>(objc_value);
  NSNumber* as_number = ObjCCast<NSNumber>(objc_value);

  if (!data && !as_string && as_number) {
    unsigned short descriptor = [as_number shortValue];
    data = [NSData dataWithBytes:&descriptor length:sizeof(descriptor)];
  }

  if (!data && as_string)
    data = [as_string dataUsingEncoding:NSUTF8StringEncoding];

  if (data) {
    value.resize([data length]);
    [data getBytes:value.data() length:value.size()];
  } else {
    LOG(WARNING) << "Unexpected value: "
                 << base::SysNSStringToUTF8([objc_value description]);
  }
  return value;
}

BluetoothRemoteGattDescriptorMac::BluetoothRemoteGattDescriptorMac(
    BluetoothRemoteGattCharacteristicMac* characteristic,
    CBDescriptor* descriptor)
    : gatt_characteristic_(characteristic),
      cb_descriptor_(descriptor, base::scoped_policy::RETAIN),
      value_read_or_write_in_progress_(false) {
  uuid_ = BluetoothAdapterMac::BluetoothUUIDWithCBUUID([cb_descriptor_ UUID]);
  identifier_ = base::SysNSStringToUTF8(
      [NSString stringWithFormat:@"%s-%p", uuid_.canonical_value().c_str(),
                                 cb_descriptor_.get()]);
}

std::string BluetoothRemoteGattDescriptorMac::GetIdentifier() const {
  return identifier_;
}

BluetoothUUID BluetoothRemoteGattDescriptorMac::GetUUID() const {
  return uuid_;
}

BluetoothGattCharacteristic::Permissions
BluetoothRemoteGattDescriptorMac::GetPermissions() const {
  NOTIMPLEMENTED();
  return BluetoothGattCharacteristic::PERMISSION_NONE;
}

const std::vector<uint8_t>& BluetoothRemoteGattDescriptorMac::GetValue() const {
  return value_;
}

BluetoothRemoteGattDescriptorMac::~BluetoothRemoteGattDescriptorMac() {
  if (!read_value_callbacks_.first.is_null()) {
    std::pair<ValueCallback, ErrorCallback> callbacks;
    callbacks.swap(read_value_callbacks_);
    callbacks.second.Run(BluetoothGattService::GATT_ERROR_FAILED);
  }
  if (!write_value_callbacks_.first.is_null()) {
    std::pair<base::Closure, ErrorCallback> callbacks;
    callbacks.swap(write_value_callbacks_);
    callbacks.second.Run(BluetoothGattService::GATT_ERROR_FAILED);
  }
}

BluetoothRemoteGattCharacteristic*
BluetoothRemoteGattDescriptorMac::GetCharacteristic() const {
  return static_cast<BluetoothRemoteGattCharacteristic*>(gatt_characteristic_);
}

// Sends a read request to a remote characteristic descriptor to read its
// value. |callback| is called to return the read value on success and
// |error_callback| is called for failures.
void BluetoothRemoteGattDescriptorMac::ReadRemoteDescriptor(
    const ValueCallback& callback,
    const ErrorCallback& error_callback) {
  if (value_read_or_write_in_progress_) {
    VLOG(1) << *this << ": Read failed, already in progress.";
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::BindOnce(error_callback,
                       BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS));
    return;
  }
  VLOG(1) << *this << ": Read value.";
  value_read_or_write_in_progress_ = true;
  read_value_callbacks_ = std::make_pair(callback, error_callback);
  [GetCBPeripheral() readValueForDescriptor:cb_descriptor_];
}

void BluetoothRemoteGattDescriptorMac::WriteRemoteDescriptor(
    const std::vector<uint8_t>& value,
    const base::Closure& callback,
    const ErrorCallback& error_callback) {
  if (value_read_or_write_in_progress_) {
    VLOG(1) << *this << ": Write failed, already in progress.";
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::BindOnce(error_callback,
                       BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS));
    return;
  }
  VLOG(1) << *this << ": Write value.";
  value_read_or_write_in_progress_ = true;
  write_value_callbacks_ = std::make_pair(callback, error_callback);
  base::scoped_nsobject<NSData> nsdata_value(
      [[NSData alloc] initWithBytes:value.data() length:value.size()]);
  [GetCBPeripheral() writeValue:nsdata_value forDescriptor:GetCBDescriptor()];
}

void BluetoothRemoteGattDescriptorMac::DidUpdateValueForDescriptor(
    NSError* error) {
  if (!value_read_or_write_in_progress_) {
    VLOG(1) << *this << ": Value updated, no read in progress.";
    return;
  }
  std::pair<ValueCallback, ErrorCallback> callbacks;
  callbacks.swap(read_value_callbacks_);
  value_read_or_write_in_progress_ = false;
  RecordDidUpdateValueForDescriptorResult(error);
  if (error) {
    BluetoothGattService::GattErrorCode error_code =
        BluetoothDeviceMac::GetGattErrorCodeFromNSError(error);
    VLOG(1) << *this << ": Read value failed with error: "
            << BluetoothAdapterMac::String(error)
            << ", converted to error code: " << error_code;
    callbacks.second.Run(error_code);
    return;
  }
  VLOG(1) << *this << ": Value read.";
  value_ = VectorValueFromObjC([cb_descriptor_ value]);
  callbacks.first.Run(value_);
}

void BluetoothRemoteGattDescriptorMac::DidWriteValueForDescriptor(
    NSError* error) {
  if (!value_read_or_write_in_progress_) {
    VLOG(1) << *this << ": Value written, no write in progress.";
    return;
  }
  std::pair<base::Closure, ErrorCallback> callbacks;
  callbacks.swap(write_value_callbacks_);
  value_read_or_write_in_progress_ = false;
  RecordDidWriteValueForDescriptorResult(error);
  if (error) {
    BluetoothGattService::GattErrorCode error_code =
        BluetoothDeviceMac::GetGattErrorCodeFromNSError(error);
    VLOG(1) << *this << ": Write value failed with error: "
            << BluetoothAdapterMac::String(error)
            << ", converted to error code: " << error_code;
    callbacks.second.Run(error_code);
    return;
  }
  VLOG(1) << *this << ": Value written.";
  callbacks.first.Run();
}

CBPeripheral* BluetoothRemoteGattDescriptorMac::GetCBPeripheral() const {
  return gatt_characteristic_->GetCBPeripheral();
}

CBDescriptor* BluetoothRemoteGattDescriptorMac::GetCBDescriptor() const {
  return cb_descriptor_;
}

DEVICE_BLUETOOTH_EXPORT std::ostream& operator<<(
    std::ostream& out,
    const BluetoothRemoteGattDescriptorMac& descriptor) {
  const BluetoothRemoteGattCharacteristicMac* characteristic_mac =
      static_cast<const BluetoothRemoteGattCharacteristicMac*>(
          descriptor.GetCharacteristic());
  return out << "<BluetoothRemoteGattDescriptorMac "
             << descriptor.GetUUID().canonical_value() << "/" << &descriptor
             << ", characteristic: "
             << characteristic_mac->GetUUID().canonical_value() << "/"
             << characteristic_mac << ">";
}

}  // namespace device.
