// Copyright 2016 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 <assert.h>
#include <errno.h>
#include <getopt.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

#include <zircon/compiler.h>
#include <zircon/syscalls.h>
#include <fbl/algorithm.h>
#include <fbl/unique_ptr.h>

namespace {

void argument_error(const char* argv0, const char* message) {
    fprintf(stderr, "%s: error: %s\nRun with -h for help.\n", argv0, message);
    exit(EXIT_FAILURE);
}

void duplicate_handles(uint32_t n, zx_handle_t src, zx_handle_t* dest) {
    for (uint32_t i = 0; i < n; i++) {
        assert(zx_handle_duplicate(src, ZX_RIGHT_SAME_RIGHTS, &dest[i]) == 0);
    }
}

struct TestArgs {
    uint32_t size;
    uint32_t handles;
    uint32_t queue;
};

void do_test(uint32_t duration, const TestArgs& test_args) {
    __UNUSED zx_status_t status;

    uint64_t duration_ns = duration * 1000000000ull;

    // We'll write to mp[0] (and read from mp[1]).
    zx_handle_t mp[2] = {ZX_HANDLE_INVALID, ZX_HANDLE_INVALID};
    status = zx_channel_create(0u, &mp[0], &mp[1]);
    assert(status == ZX_OK);

    // We'll send/receive duplicates of this handle.
    zx_handle_t event;
    assert(zx_event_create(0u, &event) == ZX_OK);

    // Storage space for our messages' stuff.
    fbl::unique_ptr<uint8_t[]> data;
    if (test_args.size) {
        data.reset(new uint8_t[test_args.size]);
        for (uint32_t i = 0; i < test_args.size; i++)
            data[i] = static_cast<uint8_t>(i);
    }
    fbl::unique_ptr<zx_handle_t[]> handles;
    if (test_args.handles)
        handles.reset(new zx_handle_t[test_args.handles]);

    // Pre-queue |test_args.queue| messages (there'll always be this many messages in the queue).
    for (uint32_t i = 0; i < test_args.queue; i++) {
        duplicate_handles(test_args.handles, event, handles.get());
        status = zx_channel_write(mp[0], 0u, data.get(), test_args.size,
                                  handles.get(), test_args.handles);
        assert(status == ZX_OK);
    }

    duplicate_handles(test_args.handles, event, handles.get());

    static constexpr uint32_t big_it_size = 10000;
    uint64_t big_its = 0;
    zx_time_t start_ns = zx_clock_get_monotonic();
    zx_time_t end_ns;
    for (;;) {
        big_its++;
        for (uint32_t i = 0; i < big_it_size; i++) {
            status = zx_channel_write(mp[0], 0, data.get(), test_args.size,
                                      handles.get(), test_args.handles);
            assert(status == ZX_OK);

            uint32_t r_size = test_args.size;
            uint32_t r_handles = test_args.handles;
            status = zx_channel_read(mp[1], 0u, data.get(), handles.get(), r_size,
                                     r_handles, &r_size, &r_handles);
            assert(status == ZX_OK);
            assert(r_size == test_args.size);
            assert(r_handles == test_args.handles);
        }

        end_ns = zx_clock_get_monotonic();
        if ((end_ns - start_ns) >= duration_ns)
            break;
    }

    for (uint32_t i = 0; i < test_args.handles; i++) {
        status = zx_handle_close(handles[i]);
        assert(status == ZX_OK);
    }
    status = zx_handle_close(event);
    assert(status == ZX_OK);
    status = zx_handle_close(mp[0]);
    assert(status == ZX_OK);
    status = zx_handle_close(mp[1]);
    assert(status == ZX_OK);

    double real_duration = static_cast<double>(end_ns - start_ns) / 1000000000.0;
    double its_per_second = static_cast<double>(big_its) * big_it_size / real_duration;
    printf("write/read %" PRIu32 " bytes, %" PRIu32 " handles (%" PRIu32 " pre-queued): "
               "%.0f iterations/second\n",
           test_args.size, test_args.handles, test_args.queue, its_per_second);
}

}  // namespace

int main(int argc, char** argv) {
    static constexpr char help[] =
        "Usage: %s [options ...]\n"
        "\n"
        "Options:\n"
        "  -h    show help (this)\n"
        "  -o    run single test (default)\n"
        "  -s    run suite (ignores -S/-H/-Q)\n"
        "  -n N  set test repetition count to N (default: 1)\n"
        "  -d N  set test duration to N seconds (default: 5)\n"
        "  -S N  set message size to N bytes (default: 10)\n"
        "  -H N  set message handle count to N handles (default: 0)\n"
        "  -Q N  set message pre-queue count to N messages (default: 0)\n";

    bool run_suite = false;  // -o/-s
    uint32_t duration = 5;   // -d
    uint32_t repeats = 1;    // -n
    // Ignored when running a suite:
    TestArgs test_args = {
        10,                  // -S (size)
        0,                   // -H (handles)
        0                    // -Q (queue)
    };

    int opt;
    while ((opt = getopt(argc, argv, "+hosn:d:S:H:Q:")) != -1) {
        // Our option values are always unsigned numbers.
        uint32_t value = 0;
        if (optarg) {
            errno = 0;
            char* endptr = nullptr;
            unsigned long long v = strtoull(optarg, &endptr, 10);
            if (errno != 0 || *endptr != '\0' || value > UINT32_MAX)
                argument_error(argv[0], "invalid numeric optional value");
            value = static_cast<uint32_t>(v);
        }

        switch (opt) {
            case 'h':
                printf(help, argv[0]);
                return EXIT_SUCCESS;
            case 'o':
                run_suite = false;
                break;
            case 's':
                run_suite = true;
                break;
            case 'n':
                assert(optarg);
                repeats = value;
                break;
            case 'd':
                assert(optarg);
                duration = value;
                break;
            case 'S':
                assert(optarg);
                test_args.size = value;
                break;
            case 'H':
                assert(optarg);
                test_args.handles = value;
                break;
            case 'Q':
                assert(optarg);
                test_args.queue = value;
                break;
            default:  // '?'
                argument_error(argv[0], "invalid option");
                break;
        }
    }
    if (optind < argc)
        argument_error(argv[0], "unexpected positional argument");

    for (uint32_t i = 0; i < repeats; i++) {
        if (repeats > 1u) {
            if (i > 0u)
                printf("\n");
            printf("Test iteration #%" PRIu32 " (of %" PRIu32 "):\n", i + 1,
                   repeats);
        }

        if (run_suite) {
            static constexpr TestArgs suite[] = {
                {10, 0, 0},
                {100, 0, 0},
                {1000, 0, 0},
                {10, 1, 0},
                {100, 1, 0},
                {1000, 1, 0},
                {10, 2, 0},
                {100, 2, 0},
                {1000, 2, 0},
                {10, 5, 0},
                {100, 5, 0},
                {1000, 5, 0},
                {10, 0, 1},
                {100, 0, 1},
                {1000, 0, 1},
            };
            for (size_t i = 0; i < fbl::count_of(suite); i++)
                do_test(duration, suite[i]);
        } else {
            do_test(duration, test_args);
        }
    }

    return EXIT_SUCCESS;
}
