// 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 <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <block-client/client.h>
#include <fuchsia/hardware/block/c/fidl.h>
#include <lib/fzl/fdio.h>
#include <lib/zx/channel.h>
#include <lib/zx/fifo.h>
#include <lib/zx/vmo.h>
#include <ramdevice-client/ramdisk.h>
#include <zircon/device/block.h>
#include <zircon/syscalls.h>
#include <zircon/time.h>
#include <zircon/types.h>

static uint64_t number(const char* str) {
  char* end;
  uint64_t n = strtoull(str, &end, 10);

  uint64_t m = 1;
  switch (*end) {
    case 'G':
    case 'g':
      m = 1024 * 1024 * 1024;
      break;
    case 'M':
    case 'm':
      m = 1024 * 1024;
      break;
    case 'K':
    case 'k':
      m = 1024;
      break;
  }
  return m * n;
}

static void bytes_per_second(uint64_t bytes, uint64_t nanos) {
  double s = ((double)nanos) / ((double)1000000000);
  double rate = ((double)bytes) / s;

  const char* unit = "B";
  if (rate > 1024 * 1024) {
    unit = "MB";
    rate /= 1024 * 1024;
  } else if (rate > 1024) {
    unit = "KB";
    rate /= 1024;
  }
  fprintf(stderr, "%g %s/s\n", rate, unit);
}

static zx_duration_t iotime_posix(int is_read, int fd, size_t total, size_t bufsz) {
  void* buffer = malloc(bufsz);
  if (buffer == NULL) {
    fprintf(stderr, "error: out of memory\n");
    return ZX_TIME_INFINITE;
  }

  zx_time_t t0 = zx_clock_get_monotonic();
  size_t n = total;
  const char* fn_name = is_read ? "read" : "write";
  while (n > 0) {
    size_t xfer = (n > bufsz) ? bufsz : n;
    ssize_t r = is_read ? read(fd, buffer, xfer) : write(fd, buffer, xfer);
    if (r < 0) {
      fprintf(stderr, "error: %s() error %d\n", fn_name, errno);
      return ZX_TIME_INFINITE;
    }
    if ((size_t)r != xfer) {
      fprintf(stderr, "error: %s() %zu of %zu bytes processed\n", fn_name, r, xfer);
      return ZX_TIME_INFINITE;
    }
    n -= xfer;
  }
  zx_time_t t1 = zx_clock_get_monotonic();

  return zx_time_sub_time(t1, t0);
}

static zx_duration_t iotime_block(int is_read, int fd, size_t total, size_t bufsz) {
  if ((total % 4096) || (bufsz % 4096)) {
    fprintf(stderr, "error: total and buffer size must be multiples of 4K\n");
    return ZX_TIME_INFINITE;
  }

  return iotime_posix(is_read, fd, total, bufsz);
}

static zx_duration_t iotime_fifo(char* dev, int is_read, int fd, size_t total, size_t bufsz) {
  zx_status_t status;
  zx::vmo vmo;
  if ((status = zx::vmo::create(bufsz, 0, &vmo)) != ZX_OK) {
    fprintf(stderr, "error: out of memory %d\n", status);
    return ZX_TIME_INFINITE;
  }

  fzl::UnownedFdioCaller disk_connection(fd);
  zx::unowned_channel channel(disk_connection.borrow_channel());
  fuchsia_hardware_block_BlockInfo info;

  zx_status_t io_status = fuchsia_hardware_block_BlockGetInfo(channel->get(), &status, &info);
  if (io_status != ZX_OK || status != ZX_OK) {
    fprintf(stderr, "error: cannot get info for '%s'\n", dev);
    return ZX_TIME_INFINITE;
  }

  zx::fifo fifo;
  io_status =
      fuchsia_hardware_block_BlockGetFifo(channel->get(), &status, fifo.reset_and_get_address());
  if (io_status != ZX_OK || status != ZX_OK) {
    fprintf(stderr, "error: cannot get fifo for '%s'\n", dev);
    return ZX_TIME_INFINITE;
  }

  groupid_t group = 0;

  zx::vmo dup;
  if ((status = vmo.duplicate(ZX_RIGHT_SAME_RIGHTS, &dup)) != ZX_OK) {
    fprintf(stderr, "error: cannot duplicate handle %d\n", status);
    return ZX_TIME_INFINITE;
  }

  fuchsia_hardware_block_VmoID vmoid;
  io_status = fuchsia_hardware_block_BlockAttachVmo(channel->get(), dup.release(), &status, &vmoid);
  if (io_status != ZX_OK || status != ZX_OK) {
    fprintf(stderr, "error: cannot attach vmo for '%s'\n", dev);
    return ZX_TIME_INFINITE;
  }

  fifo_client_t* client;
  if ((status = block_fifo_create_client(fifo.release(), &client)) != ZX_OK) {
    fprintf(stderr, "error: cannot create block client for '%s' %d\n", dev, status);
    return ZX_TIME_INFINITE;
  }

  zx_time_t t0 = zx_clock_get_monotonic();
  size_t n = total;
  while (n > 0) {
    size_t xfer = (n > bufsz) ? bufsz : n;
    block_fifo_request_t request = {
        .opcode = static_cast<uint32_t>(is_read ? BLOCKIO_READ : BLOCKIO_WRITE),
        .reqid = 0,
        .group = group,
        .vmoid = vmoid.id,
        .length = static_cast<uint32_t>(xfer / info.block_size),
        .vmo_offset = 0,
        .dev_offset = (total - n) / info.block_size,
    };
    if ((status = block_fifo_txn(client, &request, 1)) != ZX_OK) {
      fprintf(stderr, "error: block_fifo_txn error %d\n", status);
      return ZX_TIME_INFINITE;
    }
    n -= xfer;
  }
  zx_time_t t1 = zx_clock_get_monotonic();
  return zx_time_sub_time(t1, t0);
}

static int usage(void) {
  fprintf(stderr,
          "usage: iotime <read|write> <posix|block|fifo> <device|--ramdisk> <bytes> <bufsize>\n\n"
          "        <bytes> and <bufsize> must be a multiple of 4k for block mode\n"
          "        --ramdisk only supported for block mode\n");
  return -1;
}

int main(int argc, char** argv) {
  if (argc != 6) {
    return usage();
  }

  int is_read = !strcmp(argv[1], "read");
  size_t total = number(argv[4]);
  size_t bufsz = number(argv[5]);

  int r = -1;
  ramdisk_client_t* ramdisk = NULL;
  int fd;
  if (!strcmp(argv[3], "--ramdisk")) {
    if (strcmp(argv[2], "block")) {
      fprintf(stderr, "ramdisk only supported for block\n");
      goto done;
    }
    zx_status_t status = ramdisk_create(512, total / 512, &ramdisk);
    if (status != ZX_OK) {
      fprintf(stderr, "error: cannot create %zu-byte ramdisk\n", total);
      goto done;
    }
    fd = ramdisk_get_block_fd(ramdisk);
  } else {
    if ((fd = open(argv[3], is_read ? O_RDONLY : O_WRONLY)) < 0) {
      fprintf(stderr, "error: cannot open '%s'\n", argv[3]);
      goto done;
    }
  }

  zx_duration_t res;
  if (!strcmp(argv[2], "posix")) {
    res = iotime_posix(is_read, fd, total, bufsz);
  } else if (!strcmp(argv[2], "block")) {
    res = iotime_block(is_read, fd, total, bufsz);
  } else if (!strcmp(argv[2], "fifo")) {
    res = iotime_fifo(argv[3], is_read, fd, total, bufsz);
  } else {
    fprintf(stderr, "error: unknown mode '%s'\n", argv[2]);
    goto done;
  }

  if (res != ZX_TIME_INFINITE) {
    fprintf(stderr, "%s %zu bytes in %zu ns: ", is_read ? "read" : "write", total, res);
    bytes_per_second(total, res);
    r = 0;
    goto done;
  } else {
    goto done;
  }

done:
  if (ramdisk != NULL) {
    ramdisk_destroy(ramdisk);
  }
  return r;
}
