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

#include "devmgr.h"
#include "devcoordinator.h"

#include <driver-info/driver-info.h>

#include <zircon/driver/binding.h>

static bool is_driver_disabled(const char* name) {
    // driver.<driver_name>.disable
    char opt[16 + DRIVER_NAME_LEN_MAX];
    snprintf(opt, 16 + DRIVER_NAME_LEN_MAX, "driver.%s.disable", name);
    return getenv_bool(opt, false);
}

static void found_driver(zircon_driver_note_payload_t* note,
                         const zx_bind_inst_t* bi, void* cookie) {
    // ensure strings are terminated
    note->name[sizeof(note->name) - 1] = 0;
    note->vendor[sizeof(note->vendor) - 1] = 0;
    note->version[sizeof(note->version) - 1] = 0;

    if (is_driver_disabled(note->name)) {
        return;
    }

    const char* libname = cookie;
    size_t pathlen = strlen(libname) + 1;
    size_t namelen = strlen(note->name) + 1;
    size_t bindlen = note->bindcount * sizeof(zx_bind_inst_t);
    size_t len = sizeof(driver_t) + bindlen + pathlen + namelen;

    driver_t* drv;
    if ((drv = malloc(len)) == NULL) {
        return;
    }

    memset(drv, 0, sizeof(driver_t));
    drv->binding_size = bindlen;
    drv->binding = (void*) (drv + 1);
    drv->libname = (void*) (drv->binding + note->bindcount);
    drv->name = drv->libname + pathlen;

    memcpy((void*) drv->binding, bi, bindlen);
    memcpy((void*) drv->libname, libname, pathlen);
    memcpy((void*) drv->name, note->name, namelen);

#if VERBOSE_DRIVER_LOAD
    printf("found driver: %s\n", (char*) cookie);
    printf("        name: %s\n", note->name);
    printf("      vendor: %s\n", note->vendor);
    printf("     version: %s\n", note->version);
    printf("       flags: %#x\n", note->flags);
    printf("     binding:\n");
    for (size_t n = 0; n < note->bindcount; n++) {
        printf("         %03zd: %08x %08x\n", n, bi[n].op, bi[n].arg);
    }
#endif

    if (note->flags & ZIRCON_DRIVER_NOTE_FLAG_ASAN) {
        dc_asan_drivers = true;
    }

    dc_driver_added(drv, note->version);
}

void find_loadable_drivers(const char* path) {
    DIR* dir = opendir(path);
    if (dir == NULL) {
        return;
    }
    struct dirent* de;
    while ((de = readdir(dir)) != NULL) {
        if (de->d_name[0] == '.') {
            continue;
        }
        if (de->d_type != DT_REG) {
            continue;
        }
        char libname[256 + 32];
        int r = snprintf(libname, sizeof(libname), "%s/%s", path, de->d_name);
        if ((r < 0) || (r >= (int)sizeof(libname))) {
            continue;
        }

        int fd;
        if ((fd = openat(dirfd(dir), de->d_name, O_RDONLY)) < 0) {
            continue;
        }
        zx_status_t status = di_read_driver_info(fd, libname, found_driver);
        close(fd);

        if (status) {
            if (status == ZX_ERR_NOT_FOUND) {
                printf("devcoord: no driver info in '%s'\n", libname);
            } else {
                printf("devcoord: error reading info from '%s'\n", libname);
            }
        }
    }
    closedir(dir);
}

void load_driver(const char* path) {
    //TODO: check for duplicate driver add
    int fd;
    if ((fd = open(path, O_RDONLY)) < 0) {
        printf("devcoord: cannot open '%s'\n", path);
        return;
    }
    zx_status_t status = di_read_driver_info(fd, (void*)path, found_driver);
    close(fd);

    if (status) {
        if (status == ZX_ERR_NOT_FOUND) {
            printf("devcoord: no driver info in '%s'\n", path);
        } else {
            printf("devcoord: error reading info from '%s'\n", path);
        }
    }
}
