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

#include <zircon/syscalls.h>
#include <zircon/device/device.h>
#include <zircon/device/test.h>
#include <unittest/unittest.h>

#define DRIVER_TEST_DIR "/boot/driver/test"
#define DEV_TEST "/dev/misc/test"

static void do_one_test(int tfd, const char* drv_libname, zx_handle_t output, test_ioctl_test_report_t* report) {
    char devpath[1024];
    ssize_t rc = ioctl_test_create_device(tfd, drv_libname, strlen(drv_libname) + 1, devpath, sizeof(devpath));
    if (rc < 0) {
        printf("driver-tests: error %zd creating device for %s\n", rc, drv_libname);
        report->n_tests = 1;
        report->n_failed = 1;
        return;
    }

    // TODO some waiting needed before opening..,
    usleep(1000);

    int fd;
    int retry = 0;
    do {
        fd = open(devpath, O_RDWR);
        if (fd >= 0) {
            break;
        }
        usleep(1000);
    } while (++retry < 100);

    if (retry == 100) {
        printf("driver-tests: failed to open %s\n", devpath);
        report->n_tests = 1;
        report->n_failed = 1;
        goto end_device_created;
    }

    char libpath[PATH_MAX];
    int n = snprintf(libpath, sizeof(libpath), "%s/%s", DRIVER_TEST_DIR, drv_libname);
    rc = ioctl_device_bind(fd, libpath, n);
    if (rc < 0) {
        printf("driver-tests: error %zd binding to %s\n", rc, libpath);
        report->n_tests = 1;
        report->n_failed = 1;
        goto end_device_opened;
    }

    zx_handle_t h;
    zx_status_t status = zx_handle_duplicate(output, ZX_RIGHT_SAME_RIGHTS, &h);
    if (status != ZX_OK) {
        printf("driver-tests: error %d duplicating output socket\n", status);
        report->n_tests = 1;
        report->n_failed = 1;
        goto end_device_opened;
    }

    ioctl_test_set_output_socket(fd, &h);

    rc = ioctl_test_run_tests(fd, NULL, 0, report);
    if (rc < 0) {
        printf("driver-tests: error %zd running tests\n", rc);
        report->n_tests = 1;
        report->n_failed = 1;
    }

end_device_created:
    ioctl_test_destroy_device(fd);
end_device_opened:
    close(fd);
}

static int output_thread(void* arg) {
    zx_handle_t h = *(zx_handle_t*)arg;
    char buf[1024];
    for (;;) {
        zx_status_t status = zx_object_wait_one(h, ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED, ZX_TIME_INFINITE, NULL);
        if (status != ZX_OK) {
            break;
        }
        size_t bytes = 0;
        status = zx_socket_read(h, 0u, buf, sizeof(buf), &bytes);
        if (status != ZX_OK) {
            break;
        }
        size_t written = 0;
        while (written < bytes) {
            ssize_t rc = write(2, buf + written, bytes - written);
            if (rc < 0) {
                break;
            }
            written += rc;
        }
    }
    return 0;
}

int main(int argc, char** argv) {
    zx_handle_t socket[2];
    zx_status_t status = zx_socket_create(0u, socket, socket + 1);
    if (status != ZX_OK) {
        printf("driver-tests: error creating socket\n");
        return -1;
    }

    int fd = open(DEV_TEST, O_RDWR);
    if (fd < 0) {
        printf("driver-tests: no %s device found\n", DEV_TEST);
        return -1;
    }

    thrd_t t;
    int rc = thrd_create_with_name(&t, output_thread, socket, "driver-test-output");
    if (rc != thrd_success) {
        printf("driver-tests: error %d creating output thread\n", rc);
        close(fd);
        zx_handle_close(socket[0]);
        zx_handle_close(socket[1]);
        return -1;
    }

    test_ioctl_test_report_t final_report;
    memset(&final_report, 0, sizeof(final_report));

    DIR* dir = opendir(DRIVER_TEST_DIR);
    if (dir == NULL) {
        printf("driver-tests: failed to open %s\n", DRIVER_TEST_DIR);
        return -1;
    }
    int dfd = dirfd(dir);
    if (dfd < 0) {
        printf("driver-tests: failed to get fd for %s\n", DRIVER_TEST_DIR);
        return -1;
    }
    struct dirent* de;
    // bind test drivers
    while ((de = readdir(dir)) != NULL) {
        if ((strcmp(de->d_name, ".") == 0) || (strcmp(de->d_name, "..") == 0)) {
            continue;
        }
        test_ioctl_test_report_t one_report;
        memset(&one_report, 0, sizeof(one_report));
        do_one_test(fd, de->d_name, socket[1], &one_report);
        final_report.n_tests += one_report.n_tests;
        final_report.n_success += one_report.n_success;
        final_report.n_failed += one_report.n_failed;
    }
    close(fd);

    // close this handle before thrd_join to get PEER_CLOSED in output thread
    zx_handle_close(socket[1]);

    thrd_join(t, NULL);
    zx_handle_close(socket[0]);

    unittest_printf_critical(
            "\n====================================================\n");
    unittest_printf_critical(
            "    CASES:  %d     SUCCESS:  %d     FAILED:  %d   ",
            final_report.n_tests, final_report.n_success, final_report.n_failed);
    unittest_printf_critical(
            "\n====================================================\n");

    return final_report.n_failed == 0 ? 0 : -1;
}
