// 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 <fs-management/ramdisk.h>
#include <zircon/syscalls.h>
#include <zircon/device/ramdisk.h>
#include <zircon/device/block.h>
#include <block-client/client.h>

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;
}

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);
}

int usage(void);

int iotime_lread(int argc, char** argv) {
    if (argc != 5) {
        return usage();
    }
    size_t total = number(argv[3]);
    size_t bufsz = number(argv[4]);

    void* buffer = malloc(bufsz);
    if (buffer == NULL) {
        fprintf(stderr, "error: out of memory\n");
        return -1;
    }

    int fd = open(argv[2], O_RDONLY);
    if (fd < 0) {
        fprintf(stderr, "error: cannot open '%s'\n", argv[2]);
        return -1;
    }

    zx_time_t t0 = zx_time_get(ZX_CLOCK_MONOTONIC);
    size_t n = total;
    while (n > 0) {
        size_t xfer = (n > bufsz) ? bufsz : n;
        ssize_t r = read(fd, buffer, xfer);
        if (r < 0) {
            fprintf(stderr, "error: read() error %d\n", errno);
            return -1;
        }
        if ((size_t)r != xfer) {
            fprintf(stderr, "error: read() %zu of %zu bytes read\n", r, xfer);
            return -1;
        }
        n -= xfer;
    }
    zx_time_t t1 = zx_time_get(ZX_CLOCK_MONOTONIC);

    fprintf(stderr, "read %zu bytes in %zu ns: ", total, t1 - t0);
    bytes_per_second(total, t1 - t0);
    return 0;
}


int make_ramdisk(size_t blocks) {
    char ramdisk_path[PATH_MAX];
    if (create_ramdisk(512, blocks / 512, ramdisk_path)) {
        return -1;
    }

    return open(ramdisk_path, O_RDWR);
}

int iotime_bread(int argc, char** argv) {
    if (argc != 5) {
        return usage();
    }
    size_t total = number(argv[3]);
    size_t bufsz = number(argv[4]);

    if ((total % 4096) || (bufsz % 4096)) {
        fprintf(stderr, "error: total and buffer size must be multiples of 4K\n");
        return -1;
    }

    void* buffer = malloc(bufsz);
    if (buffer == NULL) {
        fprintf(stderr, "error: out of memory\n");
        return -1;
    }

    int fd;
    if (!strcmp(argv[2], "--ramdisk")) {
        if ((fd = make_ramdisk(total)) < 0) {
            fprintf(stderr, "error: cannot create %zu-byte ramdisk\n", total);
            return -1;
        }
    } else {
        if ((fd = open(argv[2], O_RDONLY)) < 0) {
            fprintf(stderr, "error: cannot open '%s'\n", argv[2]);
            return -1;
        }
    }

    zx_time_t t0 = zx_time_get(ZX_CLOCK_MONOTONIC);
    size_t n = total;
    while (n > 0) {
        size_t xfer = (n > bufsz) ? bufsz : n;
        ssize_t r = read(fd, buffer, xfer);
        if (r < 0) {
            fprintf(stderr, "error: read() error %d\n", errno);
            return -1;
        }
        if ((size_t)r != xfer) {
            fprintf(stderr, "error: read() %zu of %zu bytes read\n", r, xfer);
            return -1;
        }
        n -= xfer;
    }
    zx_time_t t1 = zx_time_get(ZX_CLOCK_MONOTONIC);

    fprintf(stderr, "read %zu bytes in %zu ns: ", total, t1 - t0);
    bytes_per_second(total, t1 - t0);
    return 0;
}

int iotime_fread(int argc, char** argv) {
    if (argc != 5) {
        return usage();
    }
    size_t total = number(argv[3]);
    size_t bufsz = number(argv[4]);

    zx_handle_t vmo;
    if (zx_vmo_create(bufsz, 0, &vmo) != ZX_OK) {
        fprintf(stderr, "error: out of memory\n");
        return -1;
    }

    int fd = open(argv[2], O_RDONLY);
    if (fd < 0) {
        fprintf(stderr, "error: cannot open '%s'\n", argv[2]);
        return -1;
    }

    zx_handle_t fifo;
    if (ioctl_block_get_fifos(fd, &fifo) != sizeof(fifo)) {
        fprintf(stderr, "err: cannot get fifo for '%s'\n", argv[2]);
        return -1;
    }

    txnid_t txnid;
    if (ioctl_block_alloc_txn(fd, &txnid) != sizeof(txnid)) {
        fprintf(stderr, "err: cannot allocate txn for '%s'\n", argv[2]);
        return -1;
    }

    zx_handle_t dup;
    if (zx_handle_duplicate(vmo, ZX_RIGHT_SAME_RIGHTS, &dup) != ZX_OK) {
        fprintf(stderr, "error: cannot duplicate handle\n");
        return -1;
    }

    vmoid_t vmoid;
    if (ioctl_block_attach_vmo(fd, &dup, &vmoid) != sizeof(vmoid)) {
        fprintf(stderr, "error: cannot attach vmo for '%s'\n", argv[2]);
        return -1;
    }

    fifo_client_t* client;
    if (block_fifo_create_client(fifo, &client) != ZX_OK) {
        fprintf(stderr, "err: cannot create block client for '%s'\n", argv[2]);
        return -1;
    }

    zx_time_t t0 = zx_time_get(ZX_CLOCK_MONOTONIC);
    size_t n = total;
    while (n > 0) {
        size_t xfer = (n > bufsz) ? bufsz : n;
        block_fifo_request_t request = {
            .txnid = txnid,
            .vmoid = vmoid,
            .opcode = BLOCKIO_READ,
            .length = xfer,
            .vmo_offset = 0,
            .dev_offset = total - n,
        };
        if (block_fifo_txn(client, &request, 1) != ZX_OK) {
            fprintf(stderr, "error: block_fifo_txn error\n");
            return -1;
        }
        n -= xfer;
    }
    zx_time_t t1 = zx_time_get(ZX_CLOCK_MONOTONIC);

    fprintf(stderr, "read %zu bytes in %zu ns: ", total, t1 - t0);
    bytes_per_second(total, t1 - t0);
    return 0;
}

int usage(void) {
    fprintf(stderr,
            "usage: iotime <op>...\n\n"
            "   op: lread <device> <bytes> <bufsize>   posix linear read\n"
            "       bread <device> <bytes> <bufsize>   block linear read\n"
            "       fread <device> <bytes> <bufsize>   fifo linear read\n");
    return -1;
}


int main(int argc, char** argv) {
    if (argc < 2) {
        return usage();
    }
    if (!strcmp(argv[1], "lread")) {
        return iotime_lread(argc, argv);
    } else if (!strcmp(argv[1], "bread")) {
        return iotime_bread(argc, argv);
    } else if (!strcmp(argv[1], "fread")) {
        return iotime_fread(argc, argv);
    } else {
        return usage();
    }
}
