/**
 * @file cmd.c
 * @author Michal Vasko <mvasko@cesnet.cz>
 * @author Radek Krejci <rkrejci@cesnet.cz>
 * @brief libyang's yanglint tool general commands
 *
 * Copyright (c) 2015-2020 CESNET, z.s.p.o.
 *
 * This source code is licensed under BSD 3-Clause License (the "License").
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://opensource.org/licenses/BSD-3-Clause
 */

#define _GNU_SOURCE

#include "cmd.h"

#include <getopt.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>

#include "common.h"
#include "compat.h"
#include "libyang.h"

COMMAND commands[];
extern int done;

#ifndef NDEBUG

void
cmd_debug_help(void)
{
    printf("Usage: debug (dict | xpath | dep-sets)+\n");
}

void
cmd_debug(struct ly_ctx **UNUSED(ctx), const char *cmdline)
{
    int argc = 0;
    char **argv = NULL;
    int opt, opt_index;
    struct option options[] = {
        {"help", no_argument, NULL, 'h'},
        {NULL, 0, NULL, 0}
    };
    uint32_t dbg_groups = 0;

    if (parse_cmdline(cmdline, &argc, &argv)) {
        goto cleanup;
    }

    while ((opt = getopt_long(argc, argv, commands[CMD_DEBUG].optstring, options, &opt_index)) != -1) {
        switch (opt) {
        case 'h':
            cmd_debug_help();
            goto cleanup;
        default:
            YLMSG_E("Unknown option.\n");
            goto cleanup;
        }
    }
    if (argc == optind) {
        /* no argument */
        cmd_debug_help();
        goto cleanup;
    }

    for (int i = 0; i < argc - optind; i++) {
        if (!strcasecmp("dict", argv[optind + i])) {
            dbg_groups |= LY_LDGDICT;
        } else if (!strcasecmp("xpath", argv[optind + i])) {
            dbg_groups |= LY_LDGXPATH;
        } else if (!strcasecmp("dep-sets", argv[optind + i])) {
            dbg_groups |= LY_LDGDEPSETS;
        } else {
            YLMSG_E("Unknown debug group \"%s\"\n", argv[optind + 1]);
            goto cleanup;
        }
    }

    ly_log_dbg_groups(dbg_groups);

cleanup:
    free_cmdline(argv);
}

#endif

void
cmd_free(void)
{
    uint16_t i;

    for (i = 0; commands[i].name; i++) {
        if (commands[i].free_func) {
            commands[i].free_func();
        }
    }
}

void
cmd_verb_help(void)
{
    printf("Usage: verb (error | warning | verbose | debug)\n");
}

void
cmd_verb(struct ly_ctx **UNUSED(ctx), const char *cmdline)
{
    int argc = 0;
    char **argv = NULL;
    int opt, opt_index;
    struct option options[] = {
        {"help", no_argument, NULL, 'h'},
        {NULL, 0, NULL, 0}
    };

    if (parse_cmdline(cmdline, &argc, &argv)) {
        goto cleanup;
    }

    while ((opt = getopt_long(argc, argv, commands[CMD_VERB].optstring, options, &opt_index)) != -1) {
        switch (opt) {
        case 'h':
            cmd_verb_help();
            goto cleanup;
        default:
            YLMSG_E("Unknown option.\n");
            goto cleanup;
        }
    }

    if (argc - optind > 1) {
        YLMSG_E("Only a single verbosity level can be set.\n");
        cmd_verb_help();
        goto cleanup;
    } else if (argc == optind) {
        /* no argument - print current value */
        LY_LOG_LEVEL level = ly_log_level(LY_LLERR);

        ly_log_level(level);
        printf("Current verbosity level: ");
        if (level == LY_LLERR) {
            printf("error\n");
        } else if (level == LY_LLWRN) {
            printf("warning\n");
        } else if (level == LY_LLVRB) {
            printf("verbose\n");
        } else if (level == LY_LLDBG) {
            printf("debug\n");
        }
        goto cleanup;
    }

    if (!strcasecmp("error", argv[optind]) || !strcmp("0", argv[optind])) {
        ly_log_level(LY_LLERR);
    } else if (!strcasecmp("warning", argv[optind]) || !strcmp("1", argv[optind])) {
        ly_log_level(LY_LLWRN);
    } else if (!strcasecmp("verbose", argv[optind]) || !strcmp("2", argv[optind])) {
        ly_log_level(LY_LLVRB);
    } else if (!strcasecmp("debug", argv[optind]) || !strcmp("3", argv[optind])) {
        ly_log_level(LY_LLDBG);
    } else {
        YLMSG_E("Unknown verbosity \"%s\"\n", argv[optind]);
        goto cleanup;
    }

cleanup:
    free_cmdline(argv);
}

void
cmd_quit(struct ly_ctx **UNUSED(ctx), const char *UNUSED(cmdline))
{
    done = 1;
    return;
}

void
cmd_help_help(void)
{
    printf("Usage: help [cmd ...]\n");
}

void
cmd_help(struct ly_ctx **UNUSED(ctx), const char *cmdline)
{
    int argc = 0;
    char **argv = NULL;
    int opt, opt_index;
    struct option options[] = {
        {"help", no_argument, NULL, 'h'},
        {NULL, 0, NULL, 0}
    };

    if (parse_cmdline(cmdline, &argc, &argv)) {
        goto cleanup;
    }

    while ((opt = getopt_long(argc, argv, commands[CMD_HELP].optstring, options, &opt_index)) != -1) {
        switch (opt) {
        case 'h':
            cmd_help_help();
            goto cleanup;
        default:
            YLMSG_E("Unknown option.\n");
            goto cleanup;
        }
    }

    if (argc == optind) {
generic_help:
        printf("Available commands:\n");
        for (uint16_t i = 0; commands[i].name; i++) {
            if (commands[i].helpstring != NULL) {
                printf("  %-15s %s\n", commands[i].name, commands[i].helpstring);
            }
        }
    } else {
        /* print specific help for the selected command(s) */

        for (int c = 0; c < argc - optind; ++c) {
            int8_t match = 0;

            /* get the command of the specified name */
            for (uint16_t i = 0; commands[i].name; i++) {
                if (strcmp(argv[optind + c], commands[i].name) == 0) {
                    match = 1;
                    if (commands[i].help_func != NULL) {
                        commands[i].help_func();
                    } else {
                        printf("%s: %s\n", argv[optind + c], commands[i].helpstring);
                    }
                    break;
                }
            }
            if (!match) {
                /* if unknown command specified, print the list of commands */
                printf("Unknown command \'%s\'\n", argv[optind + c]);
                goto generic_help;
            }
        }
    }

cleanup:
    free_cmdline(argv);
}

/* Also keep enum COMMAND_INDEX updated. */
COMMAND commands[] = {
    {"help", cmd_help, cmd_help_help, NULL, "Display commands description", "h"},
    {"add", cmd_add, cmd_add_help, NULL, "Add a new module from a specific file", "DF:hiX"},
    {"load", cmd_load, cmd_load_help, NULL, "Load a new schema from the searchdirs", "F:hiX"},
    {"print", cmd_print, cmd_print_help, NULL, "Print a module", "f:hL:o:P:q"},
    {"data", cmd_data, cmd_data_help, NULL, "Load, validate and optionally print instance data", "d:ef:F:hmo:O:R:r:nt:x:"},
    {"list", cmd_list, cmd_list_help, NULL, "List all the loaded modules", "f:h"},
    {"feature", cmd_feature, cmd_feature_help, NULL, "Print all features of module(s) with their state", "haf"},
    {"searchpath", cmd_searchpath, cmd_searchpath_help, NULL, "Print/set the search path(s) for schemas", "ch"},
    {"extdata", cmd_extdata, cmd_extdata_help, cmd_extdata_free, "Set the specific data required by an extension", "ch"},
    {"clear", cmd_clear, cmd_clear_help, NULL, "Clear the context - remove all the loaded modules", "iyhY:"},
    {"verb", cmd_verb, cmd_verb_help, NULL, "Change verbosity", "h"},
#ifndef NDEBUG
    {"debug", cmd_debug, cmd_debug_help, NULL, "Display specific debug message groups", "h"},
#endif
    {"quit", cmd_quit, NULL, NULL, "Quit the program", "h"},
    /* synonyms for previous commands */
    {"?", cmd_help, NULL, NULL, "Display commands description", "h"},
    {"exit", cmd_quit, NULL, NULL, "Quit the program", "h"},
    {NULL, NULL, NULL, NULL, NULL, NULL}
};
