// Copyright 2018 The Chromium OS 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 <memory>

#include <base/bind.h>
#include <base/logging.h>

#include "hermes/socket_qrtr.h"

#include <libqrtr.h>

namespace {

constexpr uint8_t kQrtrPort = 0;

}  // namespace

namespace hermes {

SocketQrtr::SocketQrtr() = default;

void SocketQrtr::SetDataAvailableCallback(DataAvailableCallback cb) {
  cb_ = cb;
}

bool SocketQrtr::Open() {
  if (IsValid()) {
    return true;
  }

  socket_.reset(qrtr_open(kQrtrPort));
  if (!socket_.is_valid()) {
    LOG(ERROR) << "Failed to open QRTR socket with port " << kQrtrPort;
    return false;
  }

  watcher_ = base::FileDescriptorWatcher::WatchReadable(
      socket_.get(),
      base::BindRepeating(&SocketQrtr::OnFileCanReadWithoutBlocking,
                          base::Unretained(this)));

  if (!watcher_) {
    LOG(ERROR) << "Failed to set up WatchFileDescriptor";
    socket_.reset();
    return false;
  }

  return true;
}

void SocketQrtr::Close() {
  if (IsValid()) {
    watcher_ = nullptr;
    // Since socket_ is a ScopedFD, socket_.reset() calls close() on the socket.
    socket_.reset();
  }
}

bool SocketQrtr::StartService(uint32_t service,
                              uint16_t version_major,
                              uint16_t version_minor) {
  return qrtr_new_lookup(socket_.get(), service, version_major,
                         version_minor) >= 0;
}

bool SocketQrtr::StopService(uint32_t service,
                             uint16_t version_major,
                             uint16_t version_minor) {
  return qrtr_remove_lookup(socket_.get(), service, version_major,
                            version_minor) >= 0;
}

int SocketQrtr::Recv(void* buf, size_t size, void* metadata) {
  uint32_t node, port;
  int ret = qrtr_recvfrom(socket_.get(), buf, size, &node, &port);
  VLOG(2) << "Receiving packet from node: " << node << " port: " << port;
  if (metadata) {
    PacketMetadata* data = reinterpret_cast<PacketMetadata*>(metadata);
    data->node = node;
    data->port = port;
  }
  return ret;
}

int SocketQrtr::Send(const void* data, size_t size, const void* metadata) {
  uint32_t node = 0, port = 0;
  if (metadata) {
    const PacketMetadata* data =
        reinterpret_cast<const PacketMetadata*>(metadata);
    node = data->node;
    port = data->port;
  }
  VLOG(2) << "Sending packet to node: " << node << " port: " << port;
  return qrtr_sendto(socket_.get(), node, port, data, size);
}

void SocketQrtr::OnFileCanReadWithoutBlocking() {
  if (cb_) {
    cb_.Run(this);
  }
}

bool SocketQrtr::PacketMetadata::operator==(
    const SocketQrtr::PacketMetadata& rhs) const {
  return this->port == rhs.port && this->node == rhs.node;
}

}  // namespace hermes
