// 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 "services/device/hid/hid_connection_impl.h"

#include "base/bind.h"
#include "base/memory/ref_counted_memory.h"

namespace device {

HidConnectionImpl::HidConnectionImpl(
    scoped_refptr<device::HidConnection> connection,
    mojom::HidConnectionClientPtr connection_client)
    : hid_connection_(std::move(connection)), weak_factory_(this) {
  if (connection_client) {
    hid_connection_->SetClient(this);
    client_ = std::move(connection_client);
  }
}

HidConnectionImpl::~HidConnectionImpl() {
  DCHECK(hid_connection_);
  hid_connection_->SetClient(nullptr);

  // Close |hid_connection_| on destruction because this class is owned by a
  // mojo::StrongBinding and will be destroyed when the pipe is closed.
  hid_connection_->Close();
}

void HidConnectionImpl::OnInputReport(
    scoped_refptr<base::RefCountedBytes> buffer,
    size_t size) {
  DCHECK(client_);
  uint8_t report_id = buffer->data()[0];
  uint8_t* begin = &buffer->data()[1];
  uint8_t* end = buffer->data().data() + size;
  std::vector<uint8_t> data(begin, end);
  client_->OnInputReport(report_id, data);
}

void HidConnectionImpl::Read(ReadCallback callback) {
  DCHECK(hid_connection_);
  hid_connection_->Read(base::BindOnce(&HidConnectionImpl::OnRead,
                                       weak_factory_.GetWeakPtr(),
                                       std::move(callback)));
}

void HidConnectionImpl::OnRead(ReadCallback callback,
                               bool success,
                               scoped_refptr<base::RefCountedBytes> buffer,
                               size_t size) {
  if (!success) {
    std::move(callback).Run(false, 0, base::nullopt);
    return;
  }
  DCHECK(buffer);

  std::vector<uint8_t> data(buffer->front() + 1, buffer->front() + size);
  std::move(callback).Run(true, buffer->data()[0], data);
}

void HidConnectionImpl::Write(uint8_t report_id,
                              const std::vector<uint8_t>& buffer,
                              WriteCallback callback) {
  DCHECK(hid_connection_);

  auto io_buffer =
      base::MakeRefCounted<base::RefCountedBytes>(buffer.size() + 1);
  io_buffer->data()[0] = report_id;

  memcpy(io_buffer->front() + 1, buffer.data(), buffer.size());

  hid_connection_->Write(io_buffer, base::BindOnce(&HidConnectionImpl::OnWrite,
                                                   weak_factory_.GetWeakPtr(),
                                                   std::move(callback)));
}

void HidConnectionImpl::OnWrite(WriteCallback callback, bool success) {
  std::move(callback).Run(success);
}

void HidConnectionImpl::GetFeatureReport(uint8_t report_id,
                                         GetFeatureReportCallback callback) {
  DCHECK(hid_connection_);
  hid_connection_->GetFeatureReport(
      report_id,
      base::BindOnce(&HidConnectionImpl::OnGetFeatureReport,
                     weak_factory_.GetWeakPtr(), std::move(callback)));
}

void HidConnectionImpl::OnGetFeatureReport(
    GetFeatureReportCallback callback,
    bool success,
    scoped_refptr<base::RefCountedBytes> buffer,
    size_t size) {
  if (!success) {
    std::move(callback).Run(false, base::nullopt);
    return;
  }
  DCHECK(buffer);

  std::vector<uint8_t> data(buffer->front(), buffer->front() + size);
  std::move(callback).Run(true, data);
}

void HidConnectionImpl::SendFeatureReport(uint8_t report_id,
                                          const std::vector<uint8_t>& buffer,
                                          SendFeatureReportCallback callback) {
  DCHECK(hid_connection_);

  auto io_buffer =
      base::MakeRefCounted<base::RefCountedBytes>(buffer.size() + 1);
  io_buffer->data()[0] = report_id;

  memcpy(io_buffer->front() + 1, buffer.data(), buffer.size());

  hid_connection_->SendFeatureReport(
      io_buffer,
      base::BindOnce(&HidConnectionImpl::OnSendFeatureReport,
                     weak_factory_.GetWeakPtr(), std::move(callback)));
}

void HidConnectionImpl::OnSendFeatureReport(SendFeatureReportCallback callback,
                                            bool success) {
  std::move(callback).Run(success);
}

}  // namespace device
