// Copyright 2020 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/socket.h"

#include <string>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/memory/ptr_util.h"
#include "device/bluetooth/bluetooth_socket.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "net/base/io_buffer.h"

namespace bluetooth {

Socket::Socket(scoped_refptr<device::BluetoothSocket> bluetooth_socket,
               mojo::ScopedDataPipeProducerHandle receive_stream,
               mojo::ScopedDataPipeConsumerHandle send_stream)
    : bluetooth_socket_(std::move(bluetooth_socket)),
      receive_stream_(std::move(receive_stream)),
      send_stream_(std::move(send_stream)),
      receive_stream_watcher_(FROM_HERE,
                              mojo::SimpleWatcher::ArmingPolicy::MANUAL),
      send_stream_watcher_(FROM_HERE,
                           mojo::SimpleWatcher::ArmingPolicy::MANUAL) {
  receive_stream_watcher_.Watch(
      receive_stream_.get(),
      MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
      base::BindRepeating(&Socket::OnReceiveStreamWritable,
                          base::Unretained(this)));
  send_stream_watcher_.Watch(
      send_stream_.get(),
      MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
      base::BindRepeating(&Socket::OnSendStreamReadable,
                          base::Unretained(this)));
  ReceiveMore();
  SendMore();
}

Socket::~Socket() {
  ShutdownReceive();
  ShutdownSend();
  bluetooth_socket_->Disconnect(base::DoNothing());
}

void Socket::Disconnect(DisconnectCallback callback) {
  bluetooth_socket_->Disconnect(std::move(callback));
}

void Socket::OnReceiveStreamWritable(MojoResult result) {
  DCHECK(receive_stream_.is_valid());
  if (result == MOJO_RESULT_OK) {
    ReceiveMore();
    return;
  }
  ShutdownReceive();
}

void Socket::ShutdownReceive() {
  receive_stream_watcher_.Cancel();
  receive_stream_.reset();
}

void Socket::ReceiveMore() {
  DCHECK(receive_stream_.is_valid());

  // The destination to which we will write incoming bytes from
  // |bluetooth_socket_|. The allocated buffer and its max available size
  // (assigned to |pending_write_buffer_max_size|) will be fetched by calling
  // BeginWriteData() below. This already-allocated buffer is a buffer shared
  // between the 2 sides of |receive_stream_|.
  void* pending_write_buffer = nullptr;

  // Passing 0 as the initial value allows |pending_write_buffer_max_size| to be
  // assigned the buffer's max size.
  uint32_t pending_write_buffer_max_size = 0;

  MojoResult result = receive_stream_->BeginWriteData(
      &pending_write_buffer, &pending_write_buffer_max_size,
      MOJO_WRITE_DATA_FLAG_NONE);
  if (result == MOJO_RESULT_SHOULD_WAIT) {
    receive_stream_watcher_.ArmOrNotify();
    return;
  } else if (result != MOJO_RESULT_OK) {
    ShutdownReceive();
    return;
  }

  bluetooth_socket_->Receive(
      pending_write_buffer_max_size,
      base::BindOnce(&Socket::OnBluetoothSocketReceive,
                     weak_ptr_factory_.GetWeakPtr(), pending_write_buffer),
      base::BindOnce(&Socket::OnBluetoothSocketReceiveError,
                     weak_ptr_factory_.GetWeakPtr()));
}

void Socket::OnBluetoothSocketReceive(void* pending_write_buffer,
                                      int num_bytes_received,
                                      scoped_refptr<net::IOBuffer> io_buffer) {
  DCHECK_GT(num_bytes_received, 0);
  DCHECK(io_buffer->data());

  if (!receive_stream_.is_valid())
    return;

  memcpy(pending_write_buffer, io_buffer->data(), num_bytes_received);
  receive_stream_->EndWriteData(static_cast<uint32_t>(num_bytes_received));

  ReceiveMore();
}

void Socket::OnBluetoothSocketReceiveError(
    device::BluetoothSocket::ErrorReason error_reason,
    const std::string& error_message) {
  DLOG(ERROR) << "Failed to receive data for reason '" << error_reason << "': '"
              << error_message << "'";
  if (receive_stream_.is_valid()) {
    receive_stream_->EndWriteData(0);
    ShutdownReceive();
  }
}

void Socket::OnSendStreamReadable(MojoResult result) {
  DCHECK(send_stream_.is_valid());
  if (result == MOJO_RESULT_OK)
    SendMore();
  else
    ShutdownSend();
}

void Socket::ShutdownSend() {
  send_stream_watcher_.Cancel();
  send_stream_.reset();
}

void Socket::SendMore() {
  DCHECK(send_stream_.is_valid());

  // The source from which we will write outgoing bytes to
  // |bluetooth_socket_|. The allocated buffer and the number of bytes already
  // written by the other side of |send_stream_| (assigned to
  // |pending_read_buffer_size|) will be fetched by calling BeginReadData()
  // below. This already-allocated buffer is a buffer shared between the 2 sides
  // of |send_stream_|.
  const void* pending_read_buffer = nullptr;

  // Passing 0 as the initial value allows |pending_read_buffer_size| to be
  // assigned the number of bytes that the other side of |send_stream_| has
  // already written.
  uint32_t pending_read_buffer_size = 0;

  MojoResult result = send_stream_->BeginReadData(&pending_read_buffer,
                                                  &pending_read_buffer_size,
                                                  MOJO_WRITE_DATA_FLAG_NONE);
  if (result == MOJO_RESULT_SHOULD_WAIT) {
    send_stream_watcher_.ArmOrNotify();
    return;
  } else if (result != MOJO_RESULT_OK) {
    ShutdownSend();
    return;
  }

  bluetooth_socket_->Send(base::MakeRefCounted<net::WrappedIOBuffer>(
                              static_cast<const char*>(pending_read_buffer)),
                          pending_read_buffer_size,
                          base::BindOnce(&Socket::OnBluetoothSocketSend,
                                         weak_ptr_factory_.GetWeakPtr()),
                          base::BindOnce(&Socket::OnBluetoothSocketSendError,
                                         weak_ptr_factory_.GetWeakPtr()));
}

void Socket::OnBluetoothSocketSend(int num_bytes_sent) {
  DCHECK_GE(num_bytes_sent, 0);

  if (!send_stream_.is_valid())
    return;

  send_stream_->EndReadData(static_cast<uint32_t>(num_bytes_sent));
  SendMore();
}

void Socket::OnBluetoothSocketSendError(const std::string& error_message) {
  DLOG(ERROR) << "Failed to send data: '" << error_message << "'";
  if (send_stream_.is_valid()) {
    send_stream_->EndReadData(0);
    ShutdownSend();
  }
}

}  // namespace bluetooth
