// Copyright 2017 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 "console.h"

#include <fuchsia/hardware/pty/c/fidl.h>
#include <lib/async/cpp/task.h>
#include <lib/fs-pty/service.h>
#include <lib/zx/vmar.h>
#include <string.h>

#include <algorithm>
#include <memory>
#include <utility>

#include <ddk/debug.h>
#include <ddktl/fidl.h>
#include <fbl/algorithm.h>
#include <fbl/auto_lock.h>
#include <fs/vfs.h>
#include <fs/vnode.h>
#include <virtio/virtio.h>

namespace virtio {

namespace {

zx_status_t QueueTransfer(Ring* ring, uintptr_t phys, uint32_t len, bool write) {
  uint16_t index;
  vring_desc* desc = ring->AllocDescChain(1, &index);
  if (!desc) {
    // This should not happen
    zxlogf(ERROR, "Failed to find free descriptor for the virtio ring");
    return ZX_ERR_NO_MEMORY;
  }

  desc->addr = phys;
  desc->len = len;
  // writeable for the driver is readonly for the device and vice versa
  desc->flags = write ? 0 : VRING_DESC_F_WRITE;
  ring->SubmitChain(index);

  return ZX_OK;
}

}  // namespace

TransferBuffer::TransferBuffer() { memset(&buf_, 0, sizeof(buf_)); }

TransferBuffer::~TransferBuffer() { io_buffer_release(&buf_); }

zx_status_t TransferBuffer::Init(const zx::bti& bti, size_t count, uint32_t chunk_size) {
  if (!count)
    return ZX_OK;

  count_ = count;
  chunk_size_ = chunk_size;
  size_ = count * chunk_size;

  TransferDescriptor* descriptor = new TransferDescriptor[count_];
  if (!descriptor) {
    zxlogf(ERROR, "Failed to allocate transfer descriptors (%d)", ZX_ERR_NO_MEMORY);
    return ZX_ERR_NO_MEMORY;
  }

  descriptor_.reset(descriptor, count_);

  zx_status_t status = io_buffer_init(&buf_, bti.get(), size_, IO_BUFFER_RW | IO_BUFFER_CONTIG);
  if (status != ZX_OK) {
    zxlogf(ERROR, "Failed to allocate transfer buffers (%d)", status);
    return status;
  }

  void* virt = io_buffer_virt(&buf_);
  zx_paddr_t phys = io_buffer_phys(&buf_);
  for (size_t i = 0; i < count_; ++i) {
    TransferDescriptor& desc = descriptor_[i];

    desc.virt = reinterpret_cast<uint8_t*>(virt) + i * chunk_size;
    desc.phys = phys + i * chunk_size;
    desc.total_len = chunk_size;
    desc.used_len = 0;
    desc.processed_len = 0;
  }

  return ZX_OK;
}

TransferDescriptor* TransferBuffer::GetDescriptor(size_t index) {
  if (index > count_)
    return nullptr;
  return &descriptor_[index];
}

TransferDescriptor* TransferBuffer::PhysicalToDescriptor(uintptr_t phys) {
  zx_paddr_t base = io_buffer_phys(&buf_);
  if (phys < base || phys >= base + size_)
    return nullptr;
  return &descriptor_[(phys - base) / chunk_size_];
}

void TransferQueue::Add(TransferDescriptor* desc) { queue_.push_front(desc); }

TransferDescriptor* TransferQueue::Peek() {
  if (queue_.is_empty())
    return nullptr;
  return &queue_.back();
}

TransferDescriptor* TransferQueue::Dequeue() {
  if (queue_.is_empty())
    return nullptr;
  return queue_.pop_back();
}

bool TransferQueue::IsEmpty() const { return queue_.is_empty(); }

ConsoleDevice::ConsoleDevice(zx_device_t* bus_device, zx::bti bti, std::unique_ptr<Backend> backend)
    : virtio::Device(bus_device, std::move(bti), std::move(backend)),
      ddk::Device<ConsoleDevice, ddk::Messageable>(bus_device) {}

ConsoleDevice::~ConsoleDevice() {}

// We don't need to hold request_lock_ during initialization
zx_status_t ConsoleDevice::Init() TA_NO_THREAD_SAFETY_ANALYSIS {
  zxlogf(TRACE, "%s: entry", __func__);

  zx_status_t status = zx::eventpair::create(0, &event_, &event_remote_);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: Failed to create event pair (%d)", tag(), status);
    return status;
  }

  status = loop_.StartThread("virtio-console-connection");
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: Failed to launch connection processing thread (%d)", tag(), status);
    return status;
  }

  using Vnode = fs_pty::TtyService<fs_pty::SimpleConsoleOps<ConsoleDevice*>, ConsoleDevice*>;
  console_vnode_ = fbl::AdoptRef(new Vnode(this));

  // It's a common part for all virtio devices: reset the device, notify
  // about the driver and negotiate supported features
  DeviceReset();
  DriverStatusAck();
  if (!DeviceFeatureSupported(VIRTIO_F_VERSION_1)) {
    zxlogf(ERROR, "%s: Legacy virtio interface is not supported by this driver", tag());
    return ZX_ERR_NOT_SUPPORTED;
  }
  DriverFeatureAck(VIRTIO_F_VERSION_1);

  status = DeviceStatusFeaturesOk();
  if (status) {
    zxlogf(ERROR, "%s: Feature negotiation failed (%d)", tag(), status);
    return status;
  }

  status = port0_receive_queue_.Init(0, kDescriptors);
  if (status) {
    zxlogf(ERROR, "%s: Failed to initialize receive queue (%d)", tag(), status);
    return status;
  }

  status = port0_receive_buffer_.Init(bti_, kDescriptors, kChunkSize);
  if (status) {
    zxlogf(ERROR, "%s: Failed to allocate buffers for receive queue (%d)", tag(), status);
    return status;
  }

  // Initially the whole receive buffer is available for device to write, so
  // put all descriptors in the virtio ring available list
  for (size_t i = 0; i < kDescriptors; ++i) {
    TransferDescriptor* desc = port0_receive_buffer_.GetDescriptor(i);
    QueueTransfer(&port0_receive_queue_, desc->phys, desc->total_len, /*write*/ 0);
  }
  // Notify the device
  port0_receive_queue_.Kick();

  status = port0_transmit_queue_.Init(1, kDescriptors);
  if (status) {
    zxlogf(ERROR, "%s: Failed to initialize transmit queue (%d)", tag(), status);
    return status;
  }

  status = port0_transmit_buffer_.Init(bti_, kDescriptors, kChunkSize);
  if (status) {
    zxlogf(ERROR, "%s: Failed to allocate buffers for transmit queue (%d)", tag(), status);
    return status;
  }

  // Initially the whole transmit buffer available for writing, so put all the
  // descriptors in the queue
  for (size_t i = 0; i < kDescriptors; ++i) {
    TransferDescriptor* desc = port0_transmit_buffer_.GetDescriptor(i);
    port0_transmit_descriptors_.Add(desc);
  }

  status = DdkAdd("virtio-console");
  device_ = zxdev();
  if (status) {
    zxlogf(ERROR, "%s: Failed to register device (%d)", tag(), status);
    device_ = nullptr;
    return status;
  }

  StartIrqThread();
  DriverStatusOk();

  zxlogf(TRACE, "%s: exit", __func__);
  return ZX_OK;
}

void ConsoleDevice::Unbind(ddk::UnbindTxn txn) {
  unbind_txn_ = std::move(txn);

  // Request all console connections be terminated.  Once that completes, finish
  // the unbind.
  fs::Vfs::ShutdownCallback shutdown_cb = [this](zx_status_t status) {
    if (unbind_txn_.has_value()) {
      unbind_txn_->Reply();
    } else {
      zxlogf(ERROR, "No saved unbind txn to reply to");
    }
  };
  vfs_.Shutdown(std::move(shutdown_cb));
}

void ConsoleDevice::IrqRingUpdate() {
  zxlogf(TRACE, "%s: entry", __func__);

  fbl::AutoLock a(&request_lock_);

  // These callbacks are called synchronously, so we don't need to acquire request_lock_
  port0_receive_queue_.IrqRingUpdate([this](vring_used_elem* elem) TA_NO_THREAD_SAFETY_ANALYSIS {
    uint16_t index = static_cast<uint16_t>(elem->id);
    vring_desc* desc = port0_receive_queue_.DescFromIndex(index);
    uint32_t remain = elem->len;

    for (;;) {
      bool has_next = desc->flags & VRING_DESC_F_NEXT;
      uint16_t next = desc->next;

      TransferDescriptor* trans = port0_receive_buffer_.PhysicalToDescriptor(desc->addr);

      trans->processed_len = 0;
      trans->used_len = std::min(trans->total_len, remain);
      remain -= trans->used_len;
      port0_receive_descriptors_.Add(trans);

      port0_receive_queue_.FreeDesc(index);
      if (!has_next)
        break;

      index = next;
      desc = port0_receive_queue_.DescFromIndex(index);
    }
    event_.signal_peer(0, DEV_STATE_READABLE);
  });

  port0_transmit_queue_.IrqRingUpdate([this](vring_used_elem* elem) TA_NO_THREAD_SAFETY_ANALYSIS {
    uint16_t index = static_cast<uint16_t>(elem->id);
    vring_desc* desc = port0_transmit_queue_.DescFromIndex(index);

    for (;;) {
      bool has_next = desc->flags & VRING_DESC_F_NEXT;
      uint16_t next = desc->next;

      TransferDescriptor* trans = port0_transmit_buffer_.PhysicalToDescriptor(desc->addr);

      port0_transmit_descriptors_.Add(trans);

      port0_transmit_queue_.FreeDesc(index);
      if (!has_next)
        break;

      index = next;
      desc = port0_transmit_queue_.DescFromIndex(index);
    }
    event_.signal_peer(0, DEV_STATE_WRITABLE);
  });
  zxlogf(TRACE, "%s: exit", __func__);
}

zx_status_t ConsoleDevice::Read(void* buf, size_t count, size_t* actual) {
  zxlogf(TRACE, "%s: entry", __func__);
  *actual = 0;

  if (count > UINT32_MAX)
    count = UINT32_MAX;

  fbl::AutoLock a(&request_lock_);

  TransferDescriptor* desc = port0_receive_descriptors_.Peek();
  if (!desc) {
    event_.signal_peer(DEV_STATE_READABLE, 0);
    return ZX_ERR_SHOULD_WAIT;
  }

  uint32_t len = std::min(static_cast<uint32_t>(count), desc->used_len - desc->processed_len);
  memcpy(buf, desc->virt + desc->processed_len, len);
  desc->processed_len += len;
  *actual += len;

  // Did we read the whole buffer? If so return it back to the device
  if (desc->processed_len == desc->used_len) {
    port0_receive_descriptors_.Dequeue();
    QueueTransfer(&port0_receive_queue_, desc->phys, desc->total_len, /*write*/ 0);
    port0_receive_queue_.Kick();
  }

  zxlogf(TRACE, "%s: exit", __func__);
  return ZX_OK;
}

zx_status_t ConsoleDevice::Write(const void* buf, size_t count, size_t* actual) {
  zxlogf(TRACE, "%s: entry", __func__);
  *actual = 0;

  if (count > UINT32_MAX)
    count = UINT32_MAX;

  fbl::AutoLock a(&request_lock_);

  TransferDescriptor* desc = port0_transmit_descriptors_.Dequeue();
  if (!desc) {
    event_.signal_peer(DEV_STATE_WRITABLE, 0);
    return ZX_ERR_SHOULD_WAIT;
  }

  uint32_t len = std::min(static_cast<uint32_t>(count), desc->total_len);
  memcpy(desc->virt, buf, len);
  desc->used_len = len;
  *actual += len;

  QueueTransfer(&port0_transmit_queue_, desc->phys, desc->used_len, /*write*/ 1);
  port0_transmit_queue_.Kick();

  zxlogf(TRACE, "%s: exit", __func__);
  return ZX_OK;
}

void ConsoleDevice::GetChannel(zx::channel req, GetChannelCompleter::Sync& completer) {
  // Must post a task, since ManagedVfs is not thread-safe.
  async::PostTask(loop_.dispatcher(), [this, req = std::move(req)]() mutable {
    vfs_.Serve(console_vnode_, std::move(req), fs::VnodeConnectionOptions::ReadWrite());
  });
}

zx_status_t ConsoleDevice::DdkMessage(fidl_incoming_msg_t* msg, fidl_txn_t* txn) {
  DdkTransaction transaction(txn);
  ::llcpp::fuchsia::hardware::virtioconsole::Device::Dispatch(this, msg, &transaction);
  return transaction.Status();
}

}  // namespace virtio
