// 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"

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(TEST_CONTROL_DEVICE, O_RDWR);
    if (fd < 0) {
        printf("driver-tests: no %s device found\n", TEST_CONTROL_DEVICE);
        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;
}
