// Copyright (c) 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 "device/hid/hid_connection_mac.h"

#include "base/bind.h"
#include "base/location.h"
#include "base/mac/foundation_util.h"
#include "base/numerics/safe_math.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/device_event_log/device_event_log.h"
#include "device/hid/hid_connection_mac.h"
#include "device/hid/hid_service.h"

namespace device {

namespace {

std::string HexErrorCode(IOReturn error_code) {
  return base::StringPrintf("0x%04x", error_code);
}

}  // namespace

HidConnectionMac::HidConnectionMac(base::ScopedCFTypeRef<IOHIDDeviceRef> device,
                                   scoped_refptr<HidDeviceInfo> device_info)
    : HidConnection(device_info),
      device_(std::move(device)),
      task_runner_(base::ThreadTaskRunnerHandle::Get()),
      blocking_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
          HidService::kBlockingTaskTraits)) {
  IOHIDDeviceScheduleWithRunLoop(
      device_.get(), CFRunLoopGetMain(), kCFRunLoopDefaultMode);

  size_t expected_report_size = device_info->max_input_report_size();
  if (device_info->has_report_id())
    expected_report_size++;
  inbound_buffer_.resize(expected_report_size);

  if (inbound_buffer_.size() > 0) {
    AddRef();  // Hold a reference to this while this callback is registered.
    IOHIDDeviceRegisterInputReportCallback(
        device_.get(),
        &inbound_buffer_[0],
        inbound_buffer_.size(),
        &HidConnectionMac::InputReportCallback,
        this);
  }
}

HidConnectionMac::~HidConnectionMac() {}

void HidConnectionMac::PlatformClose() {
  if (inbound_buffer_.size() > 0) {
    IOHIDDeviceRegisterInputReportCallback(
        device_.get(), &inbound_buffer_[0], inbound_buffer_.size(), NULL, this);
    // Release the reference taken when this callback was registered.
    Release();
  }

  IOHIDDeviceUnscheduleFromRunLoop(
      device_.get(), CFRunLoopGetMain(), kCFRunLoopDefaultMode);
  IOReturn result = IOHIDDeviceClose(device_.get(), 0);
  if (result != kIOReturnSuccess) {
    HID_LOG(EVENT) << "Failed to close HID device: " << HexErrorCode(result);
  }

  while (!pending_reads_.empty()) {
    pending_reads_.front().callback.Run(false, NULL, 0);
    pending_reads_.pop();
  }
}

void HidConnectionMac::PlatformRead(const ReadCallback& callback) {
  DCHECK(thread_checker().CalledOnValidThread());
  PendingHidRead pending_read;
  pending_read.callback = callback;
  pending_reads_.push(pending_read);
  ProcessReadQueue();
}

void HidConnectionMac::PlatformWrite(scoped_refptr<net::IOBuffer> buffer,
                                     size_t size,
                                     const WriteCallback& callback) {
  blocking_task_runner_->PostTask(
      FROM_HERE, base::Bind(&HidConnectionMac::SetReportAsync, this,
                            kIOHIDReportTypeOutput, buffer, size, callback));
}

void HidConnectionMac::PlatformGetFeatureReport(uint8_t report_id,
                                                const ReadCallback& callback) {
  blocking_task_runner_->PostTask(
      FROM_HERE, base::Bind(&HidConnectionMac::GetFeatureReportAsync, this,
                            report_id, callback));
}

void HidConnectionMac::PlatformSendFeatureReport(
    scoped_refptr<net::IOBuffer> buffer,
    size_t size,
    const WriteCallback& callback) {
  blocking_task_runner_->PostTask(
      FROM_HERE, base::Bind(&HidConnectionMac::SetReportAsync, this,
                            kIOHIDReportTypeFeature, buffer, size, callback));
}

// static
void HidConnectionMac::InputReportCallback(void* context,
                                           IOReturn result,
                                           void* sender,
                                           IOHIDReportType type,
                                           uint32_t report_id,
                                           uint8_t* report_bytes,
                                           CFIndex report_length) {
  HidConnectionMac* connection = static_cast<HidConnectionMac*>(context);
  if (result != kIOReturnSuccess) {
    HID_LOG(EVENT) << "Failed to read input report: " << HexErrorCode(result);
    return;
  }

  scoped_refptr<net::IOBufferWithSize> buffer;
  if (connection->device_info()->has_report_id()) {
    // report_id is already contained in report_bytes
    buffer =
        new net::IOBufferWithSize(base::checked_cast<size_t>(report_length));
    memcpy(buffer->data(), report_bytes, report_length);
  } else {
    buffer = new net::IOBufferWithSize(static_cast<size_t>(
        (base::CheckedNumeric<size_t>(report_length) + 1).ValueOrDie()));
    buffer->data()[0] = 0;
    memcpy(buffer->data() + 1, report_bytes, report_length);
  }

  connection->ProcessInputReport(buffer);
}

void HidConnectionMac::ProcessInputReport(
    scoped_refptr<net::IOBufferWithSize> buffer) {
  DCHECK(thread_checker().CalledOnValidThread());
  DCHECK_GE(buffer->size(), 1);

  uint8_t report_id = buffer->data()[0];
  if (IsReportIdProtected(report_id))
    return;

  PendingHidReport report;
  report.buffer = buffer;
  report.size = buffer->size();
  pending_reports_.push(report);
  ProcessReadQueue();
}

void HidConnectionMac::ProcessReadQueue() {
  DCHECK(thread_checker().CalledOnValidThread());

  // Hold a reference to |this| to prevent a callback from freeing this object
  // during the loop.
  scoped_refptr<HidConnectionMac> self(this);
  while (pending_reads_.size() && pending_reports_.size()) {
    PendingHidRead read = pending_reads_.front();
    PendingHidReport report = pending_reports_.front();

    pending_reads_.pop();
    pending_reports_.pop();
    read.callback.Run(true, report.buffer, report.size);
  }
}

void HidConnectionMac::GetFeatureReportAsync(uint8_t report_id,
                                             const ReadCallback& callback) {
  scoped_refptr<net::IOBufferWithSize> buffer(
      new net::IOBufferWithSize(device_info()->max_feature_report_size() + 1));
  CFIndex report_size = buffer->size();

  // The IOHIDDevice object is shared with the UI thread and so this function
  // should probably be called there but it may block and the asynchronous
  // version is NOT IMPLEMENTED. I've examined the open source implementation
  // of this function and believe it is a simple enough wrapper around the
  // kernel API that this is safe.
  IOReturn result =
      IOHIDDeviceGetReport(device_.get(),
                           kIOHIDReportTypeFeature,
                           report_id,
                           reinterpret_cast<uint8_t*>(buffer->data()),
                           &report_size);
  if (result == kIOReturnSuccess) {
    task_runner_->PostTask(
        FROM_HERE,
        base::Bind(&HidConnectionMac::ReturnAsyncResult,
                   this,
                   base::Bind(callback, true, buffer, report_size)));
  } else {
    HID_LOG(EVENT) << "Failed to get feature report: " << HexErrorCode(result);
    task_runner_->PostTask(FROM_HERE,
                           base::Bind(&HidConnectionMac::ReturnAsyncResult,
                                      this,
                                      base::Bind(callback, false, nullptr, 0)));
  }
}

void HidConnectionMac::SetReportAsync(IOHIDReportType report_type,
                                      scoped_refptr<net::IOBuffer> buffer,
                                      size_t size,
                                      const WriteCallback& callback) {
  uint8_t* data = reinterpret_cast<uint8_t*>(buffer->data());
  DCHECK_GE(size, 1u);
  uint8_t report_id = data[0];
  if (report_id == 0) {
    // OS X only expects the first byte of the buffer to be the report ID if the
    // report ID is non-zero.
    ++data;
    --size;
  }

  // The IOHIDDevice object is shared with the UI thread and so this function
  // should probably be called there but it may block and the asynchronous
  // version is NOT IMPLEMENTED. I've examined the open source implementation
  // of this function and believe it is a simple enough wrapper around the
  // kernel API that this is safe.
  IOReturn result =
      IOHIDDeviceSetReport(device_.get(), report_type, report_id, data, size);
  if (result == kIOReturnSuccess) {
    task_runner_->PostTask(FROM_HERE,
                           base::Bind(&HidConnectionMac::ReturnAsyncResult,
                                      this,
                                      base::Bind(callback, true)));
  } else {
    HID_LOG(EVENT) << "Failed to set report: " << HexErrorCode(result);
    task_runner_->PostTask(FROM_HERE,
                           base::Bind(&HidConnectionMac::ReturnAsyncResult,
                                      this,
                                      base::Bind(callback, false)));
  }
}

void HidConnectionMac::ReturnAsyncResult(const base::Closure& callback) {
  // This function is used so that the last reference to |this| can be released
  // on the thread where it was created.
  callback.Run();
}

}  // namespace device
