// Copyright 2020 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 <lib/zx/vmar.h>
#include <lib/zx/vmo.h>
#include <lib/zxio/cpp/inception.h>
#include <lib/zxio/ops.h>
#include <lib/zxio/zxio.h>
#include <limits.h>
#include <string.h>
#include <zircon/syscalls.h>

#include <algorithm>
#include <vector>

namespace fio = fuchsia_io;

static zx_status_t read_at(zxio_t* io, void* buf, size_t len, off_t offset, size_t* out_actual) {
  size_t actual = 0u;
  zx_status_t status;
  for (;;) {
    status = zxio_read_at(io, offset, buf, len, 0, &actual);
    if (status == ZX_ERR_SHOULD_WAIT) {
      zxio_signals_t observed = ZXIO_SIGNAL_NONE;
      status = zxio_wait_one(io, ZXIO_SIGNAL_READABLE | ZXIO_SIGNAL_READ_DISABLED, ZX_TIME_INFINITE,
                             &observed);
      if (status != ZX_OK) {
        return status;
      }
      // Retry reading after waiting.
      continue;
    }
    if (status != ZX_OK) {
      return status;
    }
    // Finished |zxio_read_at| successfully.
    break;
  }
  if (actual == 0) {  // EOF (?)
    return ZX_ERR_OUT_OF_RANGE;
  }
  *out_actual = actual;
  return ZX_OK;
}

static zx_status_t read_file_into_vmo(zxio_t* io, zx_handle_t* out_vmo, size_t* out_size) {
  const size_t kPageSize = zx_system_get_page_size();
  const size_t kMinWindow = kPageSize * 4;
  constexpr size_t kMaxWindow = 64 << 20;

  auto current_vmar = zx::vmar::root_self();

  zxio_node_attributes_t attr;
  zx_status_t status = zxio_attr_get(io, &attr);
  if (status != ZX_OK) {
    return status;
  }

  uint64_t size = attr.content_size;
  uint64_t offset = 0;

  zx::vmo vmo;
  status = zx::vmo::create(size, 0, &vmo);
  if (status != ZX_OK) {
    return status;
  }

  while (size > 0) {
    if (size < kMinWindow) {
      // There is little enough left that copying is less overhead
      // than fiddling with the page tables.
      std::vector<char> buffer;
      buffer.resize(kPageSize);
      size_t xfer = std::min(size, buffer.size());
      size_t nread;
      status = read_at(io, buffer.data(), xfer, offset, &nread);
      if (status != ZX_OK) {
        return status;
      }
      status = vmo.write(buffer.data(), offset, nread);
      if (status != ZX_OK) {
        return status;
      }
      offset += nread;
      size -= nread;
    } else {
      // Map the VMO into our own address space so we can read into
      // it directly and avoid double-buffering.
      size_t chunk = std::min(size, kMaxWindow);
      size_t window = (chunk + kPageSize - 1) & -kPageSize;
      uintptr_t start = 0;
      status =
          current_vmar->map(ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, 0, vmo, offset, window, &start);
      if (status != ZX_OK) {
        return status;
      }
      uint8_t* buffer = reinterpret_cast<uint8_t*>(start);
      while (chunk > 0) {
        size_t nread;
        status = read_at(io, buffer, chunk, offset, &nread);
        if (status != ZX_OK) {
          current_vmar->unmap(start, window);
          return status;
        }
        buffer += nread;
        offset += nread;
        size -= nread;
        chunk -= nread;
      }
      current_vmar->unmap(start, window);
    }
  }

  *out_vmo = vmo.release();
  if (out_size) {
    *out_size = attr.content_size;
  }
  return ZX_OK;
}

zx_status_t zxio_vmo_get_copy(zxio_t* io, zx_handle_t* out_vmo, size_t* out_size) {
  zx_status_t status = zxio_vmo_get_clone(io, out_vmo, out_size);
  if (status == ZX_OK) {
    return ZX_OK;
  }
  zx::vmo vmo;
  status = read_file_into_vmo(io, vmo.reset_and_get_address(), out_size);
  if (status != ZX_OK) {
    return status;
  }
  status = vmo.replace(ZX_RIGHTS_BASIC | ZX_RIGHTS_PROPERTY | ZX_RIGHT_READ | ZX_RIGHT_MAP, &vmo);
  if (status != ZX_OK) {
    return status;
  }
  *out_vmo = vmo.release();
  return ZX_OK;
}

zx_status_t zxio_vmo_get_clone(zxio_t* io, zx_handle_t* out_vmo, size_t* out_size) {
  return zxio_vmo_get(io, fio::wire::kVmoFlagRead | fio::wire::kVmoFlagPrivate, out_vmo, out_size);
}

zx_status_t zxio_vmo_get_exact(zxio_t* io, zx_handle_t* out_vmo, size_t* out_size) {
  return zxio_vmo_get(io, fio::wire::kVmoFlagRead | fio::wire::kVmoFlagExact, out_vmo, out_size);
}

zx_status_t zxio_vmo_get_exec(zxio_t* io, zx_handle_t* out_vmo, size_t* out_size) {
  return zxio_vmo_get(
      io, fio::wire::kVmoFlagRead | fio::wire::kVmoFlagExec | fio::wire::kVmoFlagPrivate, out_vmo,
      out_size);
}
