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

#include <fcntl.h>
#include <sys/socket.h>

#include <base/bind.h>
#include <base/callback.h>
#include <base/files/file_util.h>
#include <base/memory/ptr_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/stringprintf.h>

#include "midis/constants.h"
#include "midis/file_handler.h"
#include "midis/subdevice_client_fd_holder.h"

namespace midis {

base::FilePath Device::basedir_ = base::FilePath();

Device::Device(const std::string& name, uint32_t card, uint32_t device,
               uint32_t num_subdevices, uint32_t flags)
    : name_(name),
      card_(card),
      device_(device),
      num_subdevices_(num_subdevices),
      flags_(flags),
      weak_factory_(this) {
  LOG(INFO) << "Device created: " << name_;
}

Device::~Device() { StopMonitoring(); }

std::unique_ptr<Device> Device::Create(const std::string& name, uint32_t card,
                                       uint32_t device, uint32_t num_subdevices,
                                       uint32_t flags) {
  auto dev =
      base::MakeUnique<Device>(name, card, device, num_subdevices, flags);
  if (!dev->StartMonitoring()) {
    dev->StopMonitoring();
    return nullptr;
  }
  return dev;
}

// Cancel all the file watchers and remove the file handlers.
// This function is called if :
// a. Something has gone wrong with the Device monitor and we need to bail
// b. Something has gone wrong while adding the device.
// c. During a graceful shutdown.
void Device::StopMonitoring() {
  // Cancel all the clients FDs who were listening / writing to this device.
  client_fds_.clear();
  handlers_.clear();
}

bool Device::StartMonitoring() {
  // For each sub-device, we instantiate a fd, and an fd watcher
  // and handler messages from the device in a generic handler.
  for (uint32_t i = 0; i < num_subdevices_; i++) {
    std::string path = base::StringPrintf(
        "%s/dev/snd/midiC%uD%u", basedir_.value().c_str(), card_, device_);

    auto fh = FileHandler::Create(
        path, i,
        base::Bind(&Device::HandleReceiveData, weak_factory_.GetWeakPtr()));
    if (!fh) {
      return false;
    }
    // NOTE: If any initialization of any of the sub-device handlers fails,
    // we mark the StartMonitoring option as failed, and return false.
    // The caller should the invoke Device::StopMonitoring() to cleanup
    // the existing file handlers.
    handlers_.emplace(i, std::move(fh));
  }
  return true;
}

void Device::HandleReceiveData(const char* buffer, uint32_t subdevice,
                               size_t buf_len) const {
  LOG(INFO) << "Device: " << device_ << " Subdevice: " << subdevice
            << ", The read MIDI info is:" << buffer;
  auto list_it = client_fds_.find(subdevice);
  if (list_it != client_fds_.end()) {
    for (const auto& id_fd_entry : list_it->second) {
      // TODO(pmalani): Have a function inside subdevice client fd holder to
      // perform the write.
      ssize_t ret =
          HANDLE_EINTR(write(id_fd_entry->GetRawFd(), buffer, buf_len));
      if (ret != static_cast<ssize_t>(buf_len)) {
        PLOG(ERROR) << "Error writing to client fd.";
        // TODO(pmalani): Gracefully delete the client from all places.
      }
    }
  }
}

void Device::RemoveClientFromDevice(uint32_t client_id) {
  LOG(INFO) << "Removing the client: " << client_id
            << " from all device watchers.";
  for (auto& list_it : client_fds_) {
    for (auto it = list_it.second.begin(); it != list_it.second.end();) {
      if (it->get()->GetClientId() == client_id) {
        LOG(INFO) << "Found client: " << client_id << " in list. deleting";
        it = list_it.second.erase(it);
      } else {
        ++it;
      }
    }
  }
}

void Device::WriteClientDataToDevice(uint32_t subdevice_id,
                                     const uint8_t* buffer, size_t buf_len) {
  auto handler = handlers_.find(subdevice_id);
  if (handler != handlers_.end()) {
    handler->second->WriteData(buffer, buf_len);
  }
}

base::ScopedFD Device::AddClientToReadSubdevice(uint32_t client_id,
                                                uint32_t subdevice_id) {
  int sock_fd[2];
  int ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sock_fd);
  if (ret < 0) {
    PLOG(ERROR) << "socketpair for client_id: " << client_id
                << " device_id: " << device_ << " subdevice: " << subdevice_id
                << "failed.";
    return base::ScopedFD();
  }

  base::ScopedFD server_fd(sock_fd[0]);
  base::ScopedFD client_fd(sock_fd[1]);

  auto id_fd_list = client_fds_.find(subdevice_id);
  if (id_fd_list == client_fds_.end()) {
    std::vector<std::unique_ptr<SubDeviceClientFdHolder>> list_entries;

    list_entries.emplace_back(SubDeviceClientFdHolder::Create(
        client_id, subdevice_id, std::move(server_fd),
        base::Bind(&Device::WriteClientDataToDevice,
                   weak_factory_.GetWeakPtr())));

    client_fds_.emplace(subdevice_id, std::move(list_entries));
  } else {
    for (auto const& pair : id_fd_list->second) {
      if (pair->GetClientId() == client_id) {
        LOG(INFO) << "Client id: " << client_id
                  << " already registered to"
                     " subdevice: "
                  << subdevice_id << ".";
        return base::ScopedFD();
      }
    }
    id_fd_list->second.emplace_back(SubDeviceClientFdHolder::Create(
        client_id, subdevice_id, std::move(server_fd),
        base::Bind(&Device::WriteClientDataToDevice,
                   weak_factory_.GetWeakPtr())));
  }

  return client_fd;
}

}  // namespace midis
