// 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 <alsa/asoundlib.h>
#include <fcntl.h>
#include <sys/socket.h>

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

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

namespace {

const unsigned int kInputPortCaps =
    SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ;
const unsigned int kOutputPortCaps =
    SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE;

}  // namespace

namespace midis {

Device::Device(const std::string& name,
               const std::string& manufacturer,
               uint32_t card,
               uint32_t device,
               uint32_t num_subdevices,
               uint32_t flags,
               InPort::SubscribeCallback in_sub_cb,
               OutPort::SubscribeCallback out_sub_cb,
               InPort::DeletionCallback in_del_cb,
               OutPort::DeletionCallback out_del_cb,
               OutPort::SendMidiDataCallback send_data_cb,
               const std::map<uint32_t, unsigned int>& port_caps)
    : name_(name),
      manufacturer_(manufacturer),
      card_(card),
      device_(device),
      num_subdevices_(num_subdevices),
      flags_(flags),
      in_sub_cb_(std::move(in_sub_cb)),
      out_sub_cb_(std::move(out_sub_cb)),
      in_del_cb_(std::move(in_del_cb)),
      out_del_cb_(std::move(out_del_cb)),
      send_data_cb_(send_data_cb),
      port_caps_(port_caps),
      weak_factory_(this) {
  LOG(INFO) << "Device created: " << name_;
}

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

void Device::StopMonitoring() {
  // Cancel all the clients FDs who were listening / writing to this device.
  client_fds_.clear();
  in_ports_.clear();
  out_ports_.clear();
}

bool Device::StartMonitoring() {
  for (auto& it : port_caps_) {
    if (it.second & kInputPortCaps) {
      auto in_port = InPort::Create(device_, it.first, in_sub_cb_, in_del_cb_);
      if (in_port) {
        in_ports_.emplace(it.first, std::move(in_port));
        LOG(INFO) << "Input Port created for port:" << it.first;
      }
    }
    if (it.second & kOutputPortCaps) {
      auto out_port = OutPort::Create(device_, it.first, out_sub_cb_,
                                      out_del_cb_, send_data_cb_);
      if (out_port) {
        out_ports_.emplace(it.first, std::move(out_port));
        LOG(INFO) << "Outpot Port created for port:" << it.first;
      }
    }
  }
  return true;
}

void Device::HandleReceiveData(const char* buffer,
                               uint32_t subdevice,
                               size_t buf_len) const {
  // NOTE: We don't check whether this subdevice can actually receive data
  // because the data is coming in from the a MIDI H/W port, and so if data is
  // being generated here, it must be from a valid source.
  auto list_it = client_fds_.find(subdevice);
  if (list_it != client_fds_.end()) {
    for (const auto& id_fd_entry : list_it->second) {
      id_fd_entry->WriteDeviceDataToClient(buffer, buf_len);
    }
  }
}

void Device::RemoveClientFromDevice(uint32_t client_id) {
  LOG(INFO) << "Removing the client: " << client_id
            << " from all device watchers for device: " << name_;
  for (auto list_it = client_fds_.begin(); list_it != client_fds_.end();) {
    // First remove all clients in a subdevice.
    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;
      }
    }
    // If no clients remain, remove the subdevice entry from the map.
    if (list_it->second.empty()) {
      client_fds_.erase(list_it++);
    } else {
      ++list_it;
    }
  }

  if (client_fds_.empty()) {
    StopMonitoring();
  }
}

void Device::WriteClientDataToDevice(uint32_t subdevice_id,
                                     const uint8_t* buffer,
                                     size_t buf_len) {
  // Check whether this port supports output, otherwise just drop the data, and
  // print a warning.
  auto it = out_ports_.find(subdevice_id);
  if (it == out_ports_.end()) {
    LOG(WARNING)
        << "Data received on port: " << subdevice_id
        << " which doesn't support writing to MIDI device; dropping data";
    return;
  }
  it->second->SendData(buffer, buf_len);
}

base::ScopedFD Device::AddClientToReadSubdevice(uint32_t client_id,
                                                uint32_t subdevice_id) {
  if (client_fds_.empty()) {
    if (!StartMonitoring()) {
      LOG(ERROR) << "Couldn't start monitoring device: " << name_;
      StopMonitoring();
      return base::ScopedFD();
    }
  }

  int sock_fd[2];
  int ret = socketpair(AF_UNIX, SOCK_SEQPACKET, 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::BindRepeating(&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::BindRepeating(&Device::WriteClientDataToDevice,
                            weak_factory_.GetWeakPtr())));
  }

  return client_fd;
}

}  // namespace midis
