// Copyright 2018 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 <getopt.h>
#include <string.h>

#include <fbl/string_printf.h>
#include <fbl/unique_fd.h>
#include <fbl/unique_ptr.h>
#include <fs-test-utils/perftest.h>
#include <fuchsia/hardware/block/c/fidl.h>
#include <lib/fzl/fdio.h>
#include <lib/fzl/time.h>
#include <lib/zx/time.h>
#include <zircon/assert.h>

namespace fs_test_utils {
namespace {

constexpr char kUsage[] = R"(
Usage:

    %s [mode] [fixture options] [test options]
    Runs a set of benchmarks and write results.

    Note: Argument order matters, latest overrides earliest.

    [Mode]
        -h,--help                      Print usage description. This message.

        -p                             Performance test mode. Default mode is
                                       Unit test.

    [Fixture Options]
        --block_device PATH            The block device exposed in PATH will be
                                       used as block device.

        --use_ramdisk                  A ramdisk will be used as block device.

        --ramdisk_block_size SIZE      Size in bytes of the ramdisk's block.

        --ramdisk_block_count COUNT    Number of blocks in the ramdisk.

        --use_fvm                      A FVM will be created on the block
                                       device.

        --fvm_slice_size SIZE          Size in bytes of the FVM's slices.

        --fs FS_NAME                   Will use FS_NAME filesystem to format
                                       the block device.
                                       (Options: blobfs, minfs)

        --seed SEED                    An unsigned integer to initialize
                                       pseudo-ramdom number generator.

    [Test Options]
         --out PATH                    In performance test mode, collected
                                       results will be written to PATH.

         --summary_path PATH           In performance test mode, result summary
                                       statistics will be written to PATH.

         --print_statistics            In performance test mode, result summary
                                       statistics will be written to STDOUT.

         --runs COUNT                  In performance test mode, limits the
                                       number of times to execute each test to
                                       COUNT.

)";

// Gather some info about the executed tests, and use it to display
// gTest lookalike summary.
struct TestStats {
    uint32_t passed = 0;
    uint32_t failed = 0;
    uint32_t skipped = 0;
    uint32_t total = 0;
};

uint64_t GetDelta(zx::ticks start) {
    return (fzl::TicksToNs(zx::ticks::now() - start).to_msecs());
}

void PrintTestStart(const fbl::String& name, FILE* out) {
    if (out) {
        fprintf(out, "[ RUN      ] %s\n", name.c_str());
    }
}

void PrintTestSkipped(const fbl::String& name, zx::ticks start, FILE* out) {
    if (out) {
        fprintf(out, "[  SKIPPED ] %s(%lu ms total)\n", name.c_str(), GetDelta(start));
    }
}

void PrintTestFailed(const fbl::String& name, zx::ticks start, FILE* out) {
    if (out) {
        fprintf(out, "[   FAILED ] %s(%lu ms total)\n", name.c_str(), GetDelta(start));
    }
}

void PrintTestPassed(const fbl::String& name, zx::ticks start, FILE* out) {
    if (out) {
        fprintf(out, "[   PASSED ] %s(%lu ms total)\n", name.c_str(), GetDelta(start));
    }
}

void PrintTestCaseStart(const fbl::String& name, size_t test_count, FILE* out) {
    if (out) {
        fprintf(out, "[----------] %lu tests from %s\n", test_count, name.c_str());
    }
}

void PrintTestCaseEnd(const fbl::String& name, size_t test_count, zx::ticks start, FILE* out) {
    if (out) {
        fprintf(out, "[----------] %lu tests from %s(%lu ms total)\n\n", test_count, name.c_str(),
                GetDelta(start));
    }
}

void PrintTestsCasesSummary(size_t test_case_count, const TestStats& stats, zx::ticks start,
                            FILE* out) {
    if (out) {
        fprintf(out, "[==========] %d tests from %lu test cases ran. (%lu ms total)\n", stats.total,
                test_case_count, fzl::TicksToNs(zx::ticks::now() - start).to_msecs());
        fprintf(out, "[  PASSED  ] %d tests.\n", stats.passed);
        fprintf(out, "[  FAILED  ] %d tests.\n", stats.failed);
        fprintf(out, "[  SKIPPED ] %d tests.\n", stats.skipped);
    }
}

void PrintUsage(char* arg0, FILE* out) {
    fprintf(out, kUsage, arg0);
}

bool HasEnoughSpace(const fbl::String& block_device_path, size_t required_space) {
    if (required_space == 0) {
        return true;
    }

    fbl::unique_fd fd(open(block_device_path.c_str(), O_RDONLY));
    fzl::FdioCaller disk_caller(std::move(fd));
    fuchsia_hardware_block_BlockInfo block_info;
    zx_status_t io_status, status;
    io_status = fuchsia_hardware_block_BlockGetInfo(disk_caller.borrow_channel(), &status,
                                                    &block_info);
    if (io_status != ZX_OK || status != ZX_OK) {
        LOG_ERROR(status, "Failed to verify block_device size.\n %s\n", block_device_path.c_str());
        return false;
    }

    if (required_space > block_info.block_count * block_info.block_size) {
        return false;
    }
    return true;
}

void RunTest(const TestInfo& test, uint32_t sample_count, bool skip,
             Fixture* fixture, perftest::ResultsSet* result_set, TestStats* stats,
             FILE* out) {
    zx::ticks test_start = zx::ticks::now();
    PrintTestStart(test.name, out);
    stats->total++;
    fbl::String error;
    if (skip) {
        stats->skipped++;
        PrintTestSkipped(test.name, test_start, out);
        return;
    }
    auto test_wrapper = [&test, fixture](perftest::RepeatState* state) {
        // Reset the seed before running the test.
        *fixture->mutable_seed() = fixture->options().seed;
        bool result = test.test_fn(state, fixture);
        return result;
    };

    constexpr char kTestSuite[] = "fuchsia.zircon";
    bool failed = !perftest::RunTest(kTestSuite, test.name.c_str(), test_wrapper,
                                     sample_count, result_set, &error);
    if (failed) {
        // Log if the error is from the perftest lib.
        if (!error.empty()) {
            LOG_ERROR(ZX_ERR_INTERNAL, "%s\n", error.c_str());
        }
        stats->failed++;
        PrintTestFailed(test.name, test_start, out);
        return;
    }
    PrintTestPassed(test.name, test_start, out);
    stats->passed++;
}

// Runs all tests in the given testcase.
void RunTestCase(const FixtureOptions& fixture_options,
                 const PerformanceTestOptions& performance_test_options,
                 const TestCaseInfo& test_case, perftest::ResultsSet* result_set,
                 TestStats* global_stats, FILE* out) {
    Fixture fixture(fixture_options);

    zx::ticks start = zx::ticks::now();
    PrintTestCaseStart(test_case.name, test_case.tests.size(), out);
    bool skip_tests = (fixture.SetUpTestCase() != ZX_OK);
    bool setUp = true;
    for (auto& test : test_case.tests) {
        // Verify that the disk has enough space to run the test. This is set up by the user
        // since the actual may change depending on the test input.
        skip_tests = !HasEnoughSpace(fixture.GetFsBlockDevice(), test.required_disk_space);
        if (skip_tests) {
            LOG_ERROR(ZX_ERR_NO_SPACE, "Not enough space on disk to run test.\n");
        } else if (setUp) {
            skip_tests = (fixture.SetUp() != ZX_OK);
            setUp = false;
        }
        uint32_t actual_sample_count = test_case.sample_count;
        if (actual_sample_count == 0 || performance_test_options.is_unittest) {
            actual_sample_count = performance_test_options.sample_count;
        }
        RunTest(test, actual_sample_count, skip_tests, &fixture, result_set,
                global_stats, out);
        if (test_case.teardown) {
            fixture.TearDown();
            setUp = true;
        }
    }
    if (!test_case.teardown) {
        fixture.TearDown();
    }
    fixture.TearDownTestCase();
    PrintTestCaseEnd(test_case.name, test_case.tests.size(), start, out);
}

} // namespace

bool PerformanceTestOptions::IsValid(fbl::String* error) const {
    if (is_unittest) {
        return true;
    }

    // Something must be printed.
    if (result_path.empty() && summary_path.empty() && !print_statistics) {
        *error = "Performance test must produce output."
                 " result_path(out), summary_path or prints_statistics must be set.\n";
        return false;
    }

    if (result_path == summary_path && !result_path.empty()) {
        *error = "result_path(out) and summary_path cannot point to the same file.\n";
        return false;
    }

    if (sample_count == 0) {
        *error = "sample_count must be a positive integer.\n";
        return false;
    }

    return true;
}

bool RunTestCases(const FixtureOptions& fixture_options,
                  const PerformanceTestOptions& performance_test_options,
                  const fbl::Vector<TestCaseInfo>& test_cases, FILE* out) {
    TestStats stats;
    perftest::ResultsSet result_set;
    bool error = false;
    zx::ticks start = zx::ticks::now();
    for (auto& test_case : test_cases) {
        RunTestCase(fixture_options, performance_test_options, test_case, &result_set, &stats, out);
    }
    PrintTestsCasesSummary(test_cases.size(), stats, start, out);
    if (performance_test_options.print_statistics) {
        fprintf(out, "\n");
        result_set.PrintSummaryStatistics(out);
        fprintf(out, "\n");
    }

    if (!performance_test_options.summary_path.empty()) {
        FILE* fp = fopen(performance_test_options.summary_path.c_str(), "w");
        if (fp) {
            result_set.PrintSummaryStatistics(fp);
            fclose(fp);
        } else {
            LOG_ERROR(ZX_ERR_IO, "%s\n", strerror(errno));
            error = true;
        }
    }

    if (!performance_test_options.result_path.empty()) {
        FILE* fp = fopen(performance_test_options.result_path.c_str(), "w");
        if (fp) {
            result_set.WriteJSON(fp);
            fclose(fp);
        } else {
            LOG_ERROR(ZX_ERR_IO, "%s\n", strerror(errno));
        }
    }
    return stats.failed == 0 && !error;
}

bool ParseCommandLineArgs(int argc, const char* const* argv, FixtureOptions* fixture_options,
                          PerformanceTestOptions* performance_test_options, FILE* out) {
    static const struct option opts[] = {
        {"help", no_argument, nullptr, 'h'},
        {"block_device", required_argument, nullptr, 0},
        {"use_ramdisk", no_argument, nullptr, 0},
        {"ramdisk_block_size", required_argument, nullptr, 0},
        {"ramdisk_block_count", required_argument, nullptr, 0},
        {"use_fvm", no_argument, nullptr, 0},
        {"fvm_slice_size", required_argument, nullptr, 0},
        {"fs", required_argument, nullptr, 0},
        {"out", required_argument, nullptr, 0},
        {"summary_path", required_argument, nullptr, 0},
        {"print_statistics", no_argument, nullptr, 0},
        {"runs", required_argument, nullptr, 0},
        {"seed", required_argument, nullptr, 0},
        {0, 0, 0, 0},
    };
    // Resets the internal state of getopt*, making this function idempotent.
    optind = 0;
    bool ramdisk_set = false;
    bool block_device_set = false;

    *performance_test_options = PerformanceTestOptions::UnitTest();
    // get_opt expects non const pointers.
    char** argvs = const_cast<char**>(argv);

    int c = -1;
    int option_index = -1;
    while ((c = getopt_long(argc, argvs, "ph", opts, &option_index)) >= 0) {
        switch (c) {
        case 0:
            switch (option_index) {
            case 0:
                PrintUsage(argvs[0], out);
                return false;
            case 1:
                fixture_options->block_device_path = optarg;
                block_device_set = true;
                break;
            case 2:
                fixture_options->use_ramdisk = true;
                ramdisk_set = true;
                break;
            case 3:
                fixture_options->ramdisk_block_size = atoi(optarg);
                break;
            case 4:
                fixture_options->ramdisk_block_count = atoi(optarg);
                break;
            case 5:
                fixture_options->use_fvm = true;
                break;
            case 6:
                fixture_options->fvm_slice_size = atoi(optarg);
                break;
            case 7:
                if (strcmp(optarg, "minfs") == 0) {
                    fixture_options->fs_type = DISK_FORMAT_MINFS;
                } else if (strcmp(optarg, "blobfs") == 0) {
                    fixture_options->fs_type = DISK_FORMAT_BLOBFS;
                } else {
                    LOG_ERROR(ZX_ERR_INVALID_ARGS,
                              "Unknown disk_format %s. Support values are minfs and blobfs.\n",
                              optarg);
                    return false;
                }
                break;
            case 8:
                performance_test_options->result_path = optarg;
                break;
            case 9:
                performance_test_options->summary_path = optarg;
                break;
            case 10:
                performance_test_options->print_statistics = true;
                break;
            case 11:
                performance_test_options->sample_count = atoi(optarg);
                break;
            case 12:
                fixture_options->seed = static_cast<unsigned int>(strtoul(optarg, NULL, 0));
                break;
            default:
                break;
            }
            break;
        case 'p':
            *performance_test_options = PerformanceTestOptions::PerformanceTest();
            break;
        case 'h':
        default:
            PrintUsage(argvs[0], out);
            return false;
        }
    }

    // Unset ramdisk when not requested and block device is passed.
    if (block_device_set && !ramdisk_set) {
        fixture_options->use_ramdisk = false;
    }

    bool ok = true;
    fbl::String error;
    if (!fixture_options->IsValid(&error)) {
        LOG_ERROR(ZX_ERR_INVALID_ARGS, "%s\n", error.c_str());
        ok = false;
    }

    if (!performance_test_options->IsValid(&error)) {
        LOG_ERROR(ZX_ERR_INVALID_ARGS, "%s\n", error.c_str());
        ok = false;
    }

    if (!ok) {
        PrintUsage(argvs[0], out);
    }

    return ok;
}

} // namespace fs_test_utils
