// 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 <ddk/debug.h>
#include <lib/fdio/directory.h>
#include <fuchsia/device/c/fidl.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <zircon/syscalls.h>

static void usage(void) {
    fprintf(stderr,
            "Usage: driverctl <path> <command> [options]\n"
            "\n"
            "where path is path to driver file in /dev\n"
            "\n"
            "Command \"log\":\n"
            "  options are zero or more of:\n"
            "    \"error\" or \"e\":   DDK_LOG_ERROR\n"
            "    \"warn\" or \"w\":    DDK_LOG_WARN\n"
            "    \"info\" or \"i\":    DDK_LOG_INFO\n"
            "    \"trace\" or \"t\":   DDK_LOG_TRACE\n"
            "    \"spew\" or \"s\":    DDK_LOG_SPEW\n"
            "    \"debug1\" or \"d1\": DDK_LOG_DEBUG1\n"
            "    \"debug2\" or \"d2\": DDK_LOG_DEBUG2\n"
            "    \"debug3\" or \"d3\": DDK_LOG_DEBUG3\n"
            "    \"debug4\" or \"d4\": DDK_LOG_DEBUG4\n"
            "\n"
            "  With no options provided, driverctl log will print the current log flags for the driver.\n"
            "  A flag may have a '+' or '-' prepended. In that case the flag will be toggled\n"
            "  on (+) or off(-) without affecting other flags.\n"
            "  If toggled flags are used, all flags must be toggled.\n"
            "\n"
            "  Examples:\n"
            "\n"
            "  Set log flags to DDK_LOG_ERROR | DDK_LOG_INFO | DDK_LOG_TRACE:\n"
            "    $ driverctl <path> log error info trace\n"
            "  or:\n"
            "    $ driverctl <path> log e i t\n"
             "\n"
            "  Turn on DDK_LOG_TRACE and DDK_LOG_SPEW:\n"
            "    $ driverctl <path> log +trace +spew\n"
            "  or:\n"
            "    $ driverctl <path> log +t +s\n"
             "\n"
            "  Turn off DDK_LOG_SPEW:\n"
            "    $ driverctl <path> log -spew\n"
            "  or:\n"
            "    $ driverctl <path> log -s\n"
            );
}

int main(int argc, char **argv) {
    int ret = 0;

    if (argc < 3) {
        usage();
        return -1;
    }

    const char* path = argv[1];
    if (!strcmp(path, "-h")) {
        usage();
        return 0;
    }

    const char* command = argv[2];
    if (strcmp(command, "log")) {
        fprintf(stderr, "Unsupported command %s\n", command);
        usage();
        return -1;
    }

    zx_handle_t device, device_remote;
    if (zx_channel_create(0, &device, &device_remote) != ZX_OK) {
        fprintf(stderr, "could not create channel\n");
        return -1;
    }
    zx_status_t status = fdio_service_connect(path, device_remote);
    if (status != ZX_OK) {
        fprintf(stderr, "could not open %s\n", path);
        return -1;
    }

    if (argc == 3) {
        uint32_t flags;
        zx_status_t call_status;
        status = fuchsia_device_ControllerGetDriverLogFlags(device, &call_status, &flags);
        if (status != ZX_OK || call_status != ZX_OK) {
            fprintf(stderr, "GetDriverLogFlags failed for %s\n", path);
        } else {
            printf("Log flags:");
            if (flags & DDK_LOG_ERROR) {
                printf(" ERROR");
            }
            if (flags & DDK_LOG_WARN) {
                printf(" WARN");
            }
            if (flags & DDK_LOG_INFO) {
                printf(" INFO");
            }
            if (flags & DDK_LOG_TRACE) {
                printf(" TRACE");
            }
            if (flags & DDK_LOG_SPEW) {
                printf(" SPEW");
            }
            if (flags & DDK_LOG_DEBUG1) {
                printf(" DEBUG1");
            }
            if (flags & DDK_LOG_DEBUG2) {
                printf(" DEBUG2");
            }
            if (flags & DDK_LOG_DEBUG3) {
                printf(" DEBUG3");
            }
            if (flags & DDK_LOG_DEBUG4) {
                printf(" DEBUG4");
            }
            printf("\n");
        }
        goto out;
    }

    uint32_t clear_flags = 0;
    uint32_t set_flags = 0;
    char* toggle_arg = NULL;
    char* non_toggle_arg = NULL;

    for (int i = 3; i < argc; i++) {
        char* arg = argv[i];
        char toggle = arg[0];
        uint32_t flag = 0;

        // check for leading + or -
        if (toggle == '+' || toggle == '-') {
            toggle_arg = arg;
            arg++;
        } else {
            non_toggle_arg = arg;
        }

        if (toggle_arg && non_toggle_arg) {
            fprintf(stderr, "Cannot mix toggled flag \"%s\" with non-toggle flag \"%s\"\n",
                    toggle_arg, non_toggle_arg);
            usage();
            ret = -1;
            goto out;
        }

        if (!strcasecmp(arg, "e") || !strcasecmp(arg, "error")) {
            flag = DDK_LOG_ERROR;
        } else if (!strcasecmp(arg, "w") || !strcasecmp(arg, "warn")) {
            flag = DDK_LOG_WARN;
        } else if (!strcasecmp(arg, "i") || !strcasecmp(arg, "info")) {
            flag = DDK_LOG_INFO;
        } else if (!strcasecmp(arg, "t") || !strcasecmp(arg, "trace")) {
            flag = DDK_LOG_TRACE;
        } else if (!strcasecmp(arg, "s") || !strcasecmp(arg, "spew")) {
            flag = DDK_LOG_SPEW;
        } else if (!strcasecmp(arg, "d1") || !strcasecmp(arg, "debug1")) {
            flag = DDK_LOG_DEBUG1;
        } else if (!strcasecmp(arg, "d2") || !strcasecmp(arg, "debug2")) {
            flag = DDK_LOG_DEBUG2;
        } else if (!strcasecmp(arg, "d3") || !strcasecmp(arg, "debug3")) {
            flag = DDK_LOG_DEBUG3;
        } else if (!strcasecmp(arg, "d4") || !strcasecmp(arg, "debug4")) {
            flag = DDK_LOG_DEBUG4;
        } else {
            fprintf(stderr, "unknown flag %s\n", arg);
            ret = -1;
            goto out;
        }

        if (toggle == '+') {
            set_flags |= flag;
        } else if (toggle == '-') {
            clear_flags |= flag;
        } else {
            set_flags |= flag;
        }
    }

    if (!toggle_arg) {
        // clear all flags not explicitly set if we aren't using flag toggles
        clear_flags = ~set_flags;
    }

    zx_status_t call_status;
    status = fuchsia_device_ControllerSetDriverLogFlags(device, clear_flags, set_flags,
                                                        &call_status);
    if (status != ZX_OK || call_status != ZX_OK) {
        fprintf(stderr, "SetDriverLogFlags failed for %s\n", path);
    }

out:
    zx_handle_close(device);
    return ret;
}
