// 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/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 {

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_(in_sub_cb),
      out_sub_cb_(out_sub_cb),
      in_del_cb_(in_del_cb),
      out_del_cb_(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";
  }
  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::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
