// Copyright 2017 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 <midis/client.h>

#include <sys/socket.h>

#include <utility>

#include <base/bind.h>
#include <base/posix/eintr_wrapper.h>
#include <mojo/public/cpp/system/platform_handle.h>
#include <mojo/public/cpp/system/handle.h>

#include "midis/constants.h"

namespace midis {

Client::Client(DeviceTracker* device_tracker,
               uint32_t client_id,
               ClientDeletionCallback del_cb,
               arc::mojom::MidisServerRequest request,
               arc::mojom::MidisClientPtr client_ptr)
    : device_tracker_(device_tracker),
      client_id_(client_id),
      del_cb_(del_cb),
      client_ptr_(std::move(client_ptr)),
      binding_(this, std::move(request)),
      weak_factory_(this) {
  device_tracker_->AddDeviceObserver(this);
  binding_.set_connection_error_handler(
      base::Bind(&Client::TriggerClientDeletion, weak_factory_.GetWeakPtr()));
}

Client::~Client() {
  LOG(INFO) << "Deleting client: " << client_id_;
  device_tracker_->RemoveDeviceObserver(this);
}

void Client::TriggerClientDeletion() {
  brillo::MessageLoop::TaskId ret_id = brillo::MessageLoop::current()->PostTask(
      FROM_HERE, base::Bind(del_cb_, client_id_));
  if (ret_id == brillo::MessageLoop::kTaskIdNull) {
    LOG(ERROR) << "Couldn't schedule the client deletion callback!";
  }
}

void Client::OnDeviceAddedOrRemoved(const Device& dev, bool added) {
  arc::mojom::MidisDeviceInfoPtr dev_info = arc::mojom::MidisDeviceInfo::New();
  dev_info->card = dev.GetCard();
  dev_info->device_num = dev.GetDeviceNum();
  dev_info->num_subdevices = dev.GetNumSubdevices();
  dev_info->name = dev.GetName();
  dev_info->manufacturer = dev.GetManufacturer();
  if (added) {
    client_ptr_->OnDeviceAdded(std::move(dev_info));
  } else {
    client_ptr_->OnDeviceRemoved(std::move(dev_info));
  }
}

void Client::ListDevices(ListDevicesCallback callback) {
  // Get all the device information from device_tracker.
  std::vector<arc::mojom::MidisDeviceInfoPtr> device_list;
  device_tracker_->ListDevices(&device_list);
  std::move(callback).Run(std::move(device_list));
}

void Client::RequestPort(arc::mojom::MidisRequestPtr request,
                         RequestPortCallback callback) {
  mojo::ScopedHandle handle = CreateRequestPortFD(
      request->card, request->device_num, request->subdevice_num);
  std::move(callback).Run(std::move(handle));
}

void Client::RequestPortDeprecated(arc::mojom::MidisRequestPtr request,
                                   RequestPortDeprecatedCallback callback) {
  mojo::ScopedHandle handle = CreateRequestPortFD(
      request->card, request->device_num, request->subdevice_num);
  if (!handle.is_valid()) {
    return;
  }
  std::move(callback).Run(std::move(handle));
}

void Client::CloseDevice(arc::mojom::MidisRequestPtr request) {
  device_tracker_->RemoveClientFromDevice(client_id_, request->card,
                                          request->device_num);
}

mojo::ScopedHandle Client::CreateRequestPortFD(uint32_t card,
                                               uint32_t device,
                                               uint32_t subdevice) {
  base::ScopedFD clientfd = device_tracker_->AddClientToReadSubdevice(
      card, device, subdevice, client_id_);
  if (!clientfd.is_valid()) {
    LOG(ERROR) << "CreateRequestPortFD failed for device: " << device;
    // We don't delete the client here, because this could mean an issue with
    // the device h/w.
    return mojo::ScopedHandle();
  }

  return mojo::WrapPlatformFile(clientfd.release());
}

}  // namespace midis
