// Copyright 2018 The Fuchsia 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 "src/virtualization/bin/vmm/device/virtio_magma.h"

#include <dirent.h>
#include <fcntl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fdio/directory.h>
#include <lib/fit/defer.h>
#include <lib/syslog/cpp/log_settings.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/syslog/global.h>
#include <lib/trace-provider/provider.h>
#include <lib/trace/event.h>
#include <lib/zx/channel.h>
#include <lib/zx/vmar.h>
#include <sys/stat.h>
#include <unistd.h>
#include <zircon/status.h>

#include "src/virtualization/bin/vmm/device/magma_image.h"
#include "src/virtualization/bin/vmm/device/virtio_queue.h"

static constexpr const char* kDeviceDir = "/dev/class/gpu";

#if VIRTMAGMA_DEBUG
#define LOG_VERBOSE(msg, ...) _FX_LOGF(FX_LOG_INFO, "virtio_magma", msg, ##__VA_ARGS__)
#else
#define LOG_VERBOSE(msg, ...)
#endif

static zx_status_t InitFromImageInfo(zx::vmo vmo, ImageInfoWithToken& info,
                                     fuchsia::virtualization::hardware::VirtioImage* image) {
  if (info.token) {
    zx_status_t status = info.token.duplicate(ZX_RIGHT_SAME_RIGHTS, &image->token);
    if (status != ZX_OK)
      return status;
  }

  image->vmo = std::move(vmo);

  image->info.resize(sizeof(magma_image_info_t));
  memcpy(image->info.data(), &info.info, sizeof(magma_image_info_t));

  return ZX_OK;
}

static void InitFromVirtioImage(fuchsia::virtualization::hardware::VirtioImage& image, zx::vmo* vmo,
                                ImageInfoWithToken* info) {
  *vmo = std::move(image.vmo);
  info->token = std::move(image.token);

  assert(image.info.size() >= sizeof(magma_image_info_t));
  memcpy(&info->info, image.info.data(), sizeof(magma_image_info_t));
}

VirtioMagma::VirtioMagma(sys::ComponentContext* context) : DeviceBase(context) {}

void VirtioMagma::Start(
    fuchsia::virtualization::hardware::StartInfo start_info, zx::vmar vmar,
    fidl::InterfaceHandle<fuchsia::virtualization::hardware::VirtioWaylandImporter>
        wayland_importer,
    StartCallback callback) {
  auto deferred = fit::defer([&callback]() { callback(ZX_ERR_INTERNAL); });
  if (wayland_importer) {
    wayland_importer_ = wayland_importer.BindSync();
  }
  PrepStart(std::move(start_info));
  vmar_ = std::move(vmar);

  out_queue_.set_phys_mem(&phys_mem_);
  out_queue_.set_interrupt(
      fit::bind_member<zx_status_t, DeviceBase>(this, &VirtioMagma::Interrupt));

  auto dir = opendir(kDeviceDir);
  if (!dir) {
    FX_LOGS(ERROR) << "Failed to open device directory at " << kDeviceDir << ": "
                   << strerror(errno);
    deferred.cancel();
    callback(ZX_ERR_NOT_FOUND);
    return;
  }

  for (auto entry = readdir(dir); entry != nullptr && !device_fd_.is_valid();
       entry = readdir(dir)) {
    device_path_ = std::string(kDeviceDir) + "/" + entry->d_name;
    device_fd_ = fbl::unique_fd(open(device_path_.c_str(), O_RDONLY));
    if (!device_fd_.is_valid()) {
      FX_LOGS(WARNING) << "Failed to open device at " << device_path_ << ": " << strerror(errno);
    }
  }

  closedir(dir);

  if (!device_fd_.is_valid()) {
    FX_LOGS(ERROR) << "Failed to open any devices in " << kDeviceDir << ".";
    deferred.cancel();
    callback(ZX_ERR_NOT_FOUND);
    return;
  }

  deferred.cancel();
  callback(ZX_OK);
}

void VirtioMagma::Ready(uint32_t negotiated_features, ReadyCallback callback) {
  auto deferred = fit::defer(std::move(callback));
}

void VirtioMagma::ConfigureQueue(uint16_t queue, uint16_t size, zx_gpaddr_t desc, zx_gpaddr_t avail,
                                 zx_gpaddr_t used, ConfigureQueueCallback callback) {
  TRACE_DURATION("machina", "VirtioMagma::ConfigureQueue");
  auto deferred = fit::defer(std::move(callback));
  if (queue != 0) {
    FX_LOGS(ERROR) << "ConfigureQueue on non-existent queue " << queue;
    return;
  }
  out_queue_.Configure(size, desc, avail, used);
}

void VirtioMagma::NotifyQueue(uint16_t queue) {
  TRACE_DURATION("machina", "VirtioMagma::NotifyQueue");
  if (queue != 0) {
    return;
  }
  VirtioChain out_chain;
  while (out_queue_.NextChain(&out_chain)) {
    VirtioMagmaGeneric::HandleCommand(std::move(out_chain));
  }
}

zx_status_t VirtioMagma::Handle_device_import(const virtio_magma_device_import_ctrl_t* request,
                                              virtio_magma_device_import_resp_t* response) {
  zx::channel server_handle, client_handle;
  zx_status_t status = zx::channel::create(0u, &server_handle, &client_handle);
  if (status != ZX_OK)
    return status;
  status = fdio_service_connect(device_path_.c_str(), server_handle.release());
  if (status != ZX_OK) {
    LOG_VERBOSE("fdio_service_connect failed %d", status);
    return status;
  }

  auto modified = *request;
  modified.device_channel = client_handle.release();
  return VirtioMagmaGeneric::Handle_device_import(&modified, response);
}

zx_status_t VirtioMagma::Handle_release_connection(
    const virtio_magma_release_connection_ctrl_t* request,
    virtio_magma_release_connection_resp_t* response) {
  zx_status_t status = VirtioMagmaGeneric::Handle_release_connection(request, response);
  if (status != ZX_OK)
    return ZX_OK;

  auto connection = reinterpret_cast<magma_connection_t>(request->connection);

  connection_image_map_.erase(connection);

  return ZX_OK;
}

zx_status_t VirtioMagma::Handle_release_buffer(const virtio_magma_release_buffer_ctrl_t* request,
                                               virtio_magma_release_buffer_resp_t* response) {
  zx_status_t status = VirtioMagmaGeneric::Handle_release_buffer(request, response);
  if (status != ZX_OK)
    return ZX_OK;

  auto connection = reinterpret_cast<magma_connection_t>(request->connection);

  auto& image_map = connection_image_map_[connection];
  image_map.erase(request->buffer);

  return ZX_OK;
}

zx_status_t VirtioMagma::Handle_internal_map(const virtio_magma_internal_map_ctrl_t* request,
                                             virtio_magma_internal_map_resp_t* response) {
  FX_DCHECK(request->hdr.type == VIRTIO_MAGMA_CMD_INTERNAL_MAP);

  response->address_out = 0;
  response->hdr.type = VIRTIO_MAGMA_RESP_INTERNAL_MAP;

  magma_handle_t handle;
  response->result_return =
      magma_get_buffer_handle(reinterpret_cast<magma_connection_t>(request->connection),
                              reinterpret_cast<magma_buffer_t>(request->buffer), &handle);
  if (response->result_return != MAGMA_STATUS_OK)
    return ZX_OK;

  zx::vmo vmo(handle);

  zx_vaddr_t zx_vaddr;
  zx_status_t zx_status = vmar_.map(ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, 0 /*vmar_offset*/, vmo,
                                    0 /* vmo_offset */, request->length, &zx_vaddr);
  if (zx_status != ZX_OK) {
    FX_LOGS(ERROR) << "vmar map (length " << request->length << ") failed: " << zx_status;
    response->result_return = MAGMA_STATUS_INVALID_ARGS;
    return zx_status;
  }

  const uint64_t buffer_id = magma_get_buffer_id(reinterpret_cast<magma_buffer_t>(request->buffer));
  buffer_maps_.emplace(buffer_id, std::pair<zx_vaddr_t, size_t>(zx_vaddr, request->length));

  response->address_out = zx_vaddr;

  return ZX_OK;
}

zx_status_t VirtioMagma::Handle_internal_unmap(const virtio_magma_internal_unmap_ctrl_t* request,
                                               virtio_magma_internal_unmap_resp_t* response) {
  FX_DCHECK(request->hdr.type == VIRTIO_MAGMA_CMD_INTERNAL_UNMAP);

  response->hdr.type = VIRTIO_MAGMA_RESP_INTERNAL_UNMAP;

  uint64_t buffer_id = magma_get_buffer_id(reinterpret_cast<magma_buffer_t>(request->buffer));

  for (auto iter = buffer_maps_.find(buffer_id); iter != buffer_maps_.end(); iter++) {
    const auto& mapping = iter->second;
    const zx_vaddr_t mapped_addr = mapping.first;
    const size_t length = mapping.second;

    if (request->address == mapped_addr) {
      buffer_maps_.erase(iter);

      zx_status_t zx_status = vmar_.unmap(mapped_addr, length);
      if (zx_status != ZX_OK) {
        response->result_return = MAGMA_STATUS_INTERNAL_ERROR;
        return zx_status;
      }
      response->result_return = MAGMA_STATUS_OK;
      return ZX_OK;
    }
  }

  response->result_return = MAGMA_STATUS_INVALID_ARGS;
  return ZX_OK;
}

zx_status_t VirtioMagma::Handle_poll(const virtio_magma_poll_ctrl_t* request,
                                     virtio_magma_poll_resp_t* response) {
  auto request_mod = *request;
  // The actual items immediately follow the request struct.
  request_mod.items = reinterpret_cast<uint64_t>(&request[1]);
  // Transform byte count back to item count
  request_mod.count /= sizeof(magma_poll_item_t);
  return VirtioMagmaGeneric::Handle_poll(&request_mod, response);
}

zx_status_t VirtioMagma::Handle_read_notification_channel2(
    const virtio_magma_read_notification_channel2_ctrl_t* request,
    virtio_magma_read_notification_channel2_resp_t* response) {
  auto request_mod = *request;
  // The notification data immediately follows the response struct.
  request_mod.buffer = reinterpret_cast<uint64_t>(&response[1]);
  return VirtioMagmaGeneric::Handle_read_notification_channel2(&request_mod, response);
}

zx_status_t VirtioMagma::Handle_export(const virtio_magma_export_ctrl_t* request,
                                       virtio_magma_export_resp_t* response) {
  if (!wayland_importer_) {
    LOG_VERBOSE("driver attempted to export a buffer without wayland present");
    response->hdr.type = VIRTIO_MAGMA_RESP_EXPORT;
    response->buffer_handle_out = 0;
    response->result_return = MAGMA_STATUS_UNIMPLEMENTED;
    return ZX_OK;
  }

  // We only export images
  fuchsia::virtualization::hardware::VirtioImage image;

  {
    auto& image_map =
        connection_image_map_[reinterpret_cast<magma_connection_t>(request->connection)];

    auto iter = image_map.find(request->buffer);
    if (iter == image_map.end()) {
      response->hdr.type = VIRTIO_MAGMA_RESP_EXPORT;
      response->buffer_handle_out = 0;
      response->result_return = MAGMA_STATUS_INVALID_ARGS;
      return ZX_OK;
    }

    ImageInfoWithToken& info = iter->second;

    // Get the VMO handle for this buffer.
    zx_status_t status = VirtioMagmaGeneric::Handle_export(request, response);
    if (status != ZX_OK) {
      LOG_VERBOSE("VirtioMagmaGeneric::Handle_export failed: %d", status);
      return status;
    }

    // Take ownership of the VMO handle.
    zx::vmo vmo(static_cast<zx_handle_t>(response->buffer_handle_out));
    response->buffer_handle_out = 0;

    status = InitFromImageInfo(std::move(vmo), info, &image);
    if (status != ZX_OK) {
      LOG_VERBOSE("InitFromImageInfo failed: %d", status);
      return status;
    }
  }

  // TODO(fxbug.dev/13261): improvement backlog
  // Perform a blocking import of the image, then return the VFD ID in the response.
  // Note that since the virtio-magma device is fully synchronous anyway, this does
  // not impact performance. Ideally, the device would stash the response chain and
  // return it only when the Import call returns, processing messages from other
  // instances, or even other connections, in the meantime.
  uint32_t vfd_id;
  zx_status_t status = wayland_importer_->ImportImage(std::move(image), &vfd_id);
  if (status != ZX_OK) {
    LOG_VERBOSE("ImportImage failed: %d", status);
    return status;
  }

  response->buffer_handle_out = vfd_id;

  return ZX_OK;
}

zx_status_t VirtioMagma::Handle_import(const virtio_magma_import_ctrl_t* request,
                                       virtio_magma_import_resp_t* response) {
  if (!wayland_importer_) {
    LOG_VERBOSE("driver attempted to import a buffer without wayland present");
    response->hdr.type = VIRTIO_MAGMA_RESP_IMPORT;
    response->result_return = MAGMA_STATUS_UNIMPLEMENTED;
    return ZX_OK;
  }

  uint32_t vfd_id = request->buffer_handle;

  std::unique_ptr<fuchsia::virtualization::hardware::VirtioImage> image;
  zx_status_t result;

  zx_status_t status = wayland_importer_->ExportImage(vfd_id, &result, &image);
  if (status != ZX_OK) {
    LOG_VERBOSE("VirtioWl ExportImage failed: %d", status);
    return status;
  }
  assert(image);

  if (result != ZX_OK) {
    LOG_VERBOSE("VirtioWl ExportImage returned result: %d", status);
    return result;
  }

  ImageInfoWithToken info;
  zx::vmo vmo;

  InitFromVirtioImage(*image.get(), &vmo, &info);

  {
    virtio_magma_import_ctrl_t request_copy = *request;
    request_copy.buffer_handle = vmo.release();

    status = VirtioMagmaGeneric::Handle_import(&request_copy, response);
    if (status != ZX_OK)
      return status;
  }

  {
    auto& image_map =
        connection_image_map_[reinterpret_cast<magma_connection_t>(request->connection)];

    magma_buffer_t image = response->buffer_out;
    image_map[image] = std::move(info);
  }

  return ZX_OK;
}

zx_status_t VirtioMagma::Handle_execute_command_buffer_with_resources(
    const virtio_magma_execute_command_buffer_with_resources_ctrl_t* request,
    virtio_magma_execute_command_buffer_with_resources_resp_t* response) {
  // Command buffer payload comes immediately after the request
  auto command_buffer = reinterpret_cast<magma_system_command_buffer*>(
      const_cast<virtio_magma_execute_command_buffer_with_resources_ctrl_t*>(request) + 1);
  auto exec_resources = reinterpret_cast<magma_system_exec_resource*>(command_buffer + 1);
  auto semaphore_ids = reinterpret_cast<uint64_t*>(exec_resources + command_buffer->resource_count);

  virtio_magma_execute_command_buffer_with_resources_ctrl_t request_dupe;
  memcpy(&request_dupe, request, sizeof(request_dupe));

  request_dupe.command_buffer = reinterpret_cast<uintptr_t>(command_buffer);
  request_dupe.resources = reinterpret_cast<uintptr_t>(exec_resources);
  request_dupe.semaphore_ids = reinterpret_cast<uintptr_t>(semaphore_ids);

  return VirtioMagmaGeneric::Handle_execute_command_buffer_with_resources(&request_dupe, response);
}

zx_status_t VirtioMagma::Handle_virt_create_image(
    const virtio_magma_virt_create_image_ctrl_t* request,
    virtio_magma_virt_create_image_resp_t* response) {
  // Copy create info to ensure proper alignment
  magma_image_create_info_t image_create_info;
  memcpy(&image_create_info, reinterpret_cast<const magma_image_create_info_t*>(request + 1),
         sizeof(image_create_info));

  ImageInfoWithToken image_info;
  zx::vmo vmo;

  response->hdr.type = VIRTIO_MAGMA_RESP_VIRT_CREATE_IMAGE;
  // Assuming the current connection is on the one and only physical device.
  uint32_t physical_device_index = 0;
  response->result_return = magma_image::CreateDrmImage(physical_device_index, &image_create_info,
                                                        &image_info.info, &vmo, &image_info.token);

  if (response->result_return != MAGMA_STATUS_OK)
    return ZX_OK;

  auto connection = reinterpret_cast<magma_connection_t>(request->connection);

  {
    magma_buffer_t image;
    response->result_return = magma_import(connection, vmo.release(), &image);
    if (response->result_return != MAGMA_STATUS_OK) {
      printf("Failed to import VMO\n");
      return ZX_OK;
    }

    response->image_out = image;
  }

  auto& map = connection_image_map_[connection];

  map[response->image_out] = std::move(image_info);

  return ZX_OK;
}

zx_status_t VirtioMagma::Handle_virt_get_image_info(
    const virtio_magma_virt_get_image_info_ctrl_t* request,
    virtio_magma_virt_get_image_info_resp_t* response) {
  response->hdr.type = VIRTIO_MAGMA_RESP_VIRT_GET_IMAGE_INFO;

  auto connection = reinterpret_cast<magma_connection_t>(request->connection);

  auto& map = connection_image_map_[connection];

  auto iter = map.find(request->image);
  if (iter == map.end()) {
    response->result_return = MAGMA_STATUS_INVALID_ARGS;
    return ZX_OK;
  }

  ImageInfoWithToken& image_info = iter->second;

  auto image_info_out = reinterpret_cast<magma_image_info_t*>(
      const_cast<virtio_magma_virt_get_image_info_ctrl_t*>(request) + 1);
  *image_info_out = image_info.info;

  response->result_return = MAGMA_STATUS_OK;
  return ZX_OK;
}

int main(int argc, char** argv) {
  syslog::SetTags({"virtio_magma"});

  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
  trace::TraceProviderWithFdio trace_provider(loop.dispatcher());
  std::unique_ptr<sys::ComponentContext> context =
      sys::ComponentContext::CreateAndServeOutgoingDirectory();

  VirtioMagma virtio_magma(context.get());
  return loop.Run();
}
