/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "os/mynewt.h"
#include "console/console.h"
#include "shell/shell.h"
#include "shell_priv.h"

#define SHELL_PROMPT "shell"

static struct shell_module shell_modules[MYNEWT_VAL(SHELL_MAX_MODULES)];
static size_t num_of_shell_entities;

static const char *prompt;
static int default_module = -1;

static shell_cmd_func_t app_cmd_handler;
static shell_prompt_function_t app_prompt_handler;

/* Shared queue for shell events to be processed */
static struct os_eventq *shell_evq;
/* Queue for available shell events */
static struct os_event shell_console_ev[MYNEWT_VAL(SHELL_MAX_CMD_QUEUED)];
static struct console_input buf[MYNEWT_VAL(SHELL_MAX_CMD_QUEUED)];

void
shell_evq_set(struct os_eventq *evq)
{
    shell_evq = evq;
    console_line_queue_set(shell_evq);
}

static const char *
get_prompt(void)
{
    const char *str;

    if (app_prompt_handler) {

        str = app_prompt_handler();
        if (str) {
            return str;
        }
    }

    if (default_module != -1) {
        return shell_modules[default_module].name;
    }

    return prompt;
}

static void
print_prompt(void)
{
    console_printf("%s%s", get_prompt(), MYNEWT_VAL(SHELL_PROMPT_SUFFIX));
}

static size_t
line2argv(char *str, char *argv[], size_t size)
{
    size_t argc = 0;

    if (!strlen(str)) {
        return 0;
    }

    while (*str && *str == ' ') {
        str++;
    }

    if (!*str) {
        return 0;
    }

    argv[argc++] = str;

    while ((str = strchr(str, ' '))) {
        *str++ = '\0';

        while (*str && *str == ' ') {
            str++;
        }

        if (!*str) {
            break;
        }

        argv[argc++] = str;

        if (argc == size) {
            console_printf("Too many parameters (max %zu)\n", size - 1);
            return 0;
        }
    }

    /* keep it POSIX style where argv[argc] is required to be NULL */
    argv[argc] = NULL;

    return argc;
}

static int
get_destination_module(const char *module_str, int len)
{
    int i;

    for (i = 0; i < num_of_shell_entities; i++) {
        if (len < 0) {
            if (!strcmp(module_str, shell_modules[i].name)) {
                return i;
            }
        } else {
            if (!strncmp(module_str, shell_modules[i].name, len)) {
                return i;
            }
        }
    }

    return -1;
}

/* For a specific command: argv[0] = module name, argv[1] = command name
 * If a default module was selected: argv[0] = command name
 */
static const char *
get_command_and_module(char *argv[], int *module)
{
    *module = -1;

    if (!argv[0]) {
        console_printf("Unrecognized command\n");
        return NULL;
    }

    if (default_module == -1) {
        if (!argv[1] || argv[1][0] == '\0') {
            console_printf("Unrecognized command: %s\n", argv[0]);
            return NULL;
        }

        *module = get_destination_module(argv[0], -1);
        if (*module == -1) {
            console_printf("Illegal module %s\n", argv[0]);
            return NULL;
        }

        return argv[1];
    }

    *module = default_module;
    return argv[0];
}

static void
print_command_params(const int module, const int command)
{
	const struct shell_module *shell_module = &shell_modules[module];
	const struct shell_cmd *shell_cmd = &shell_module->commands[command];
	int i;

	if (!(shell_cmd->help && shell_cmd->help->params)) {
		return;
	}

	for (i = 0; shell_cmd->help->params[i].param_name; i++) {
		console_printf("%-30s%s\n", shell_cmd->help->params[i].param_name,
			       shell_cmd->help->params[i].help);
	}
}

static int
show_cmd_help(char *argv[])
{
    const char *command = NULL;
    int module = -1;
    const struct shell_module *shell_module = NULL;
    const struct shell_cmd *cmd;
    int i;

    command = get_command_and_module(argv, &module);
    if ((module == -1) || (command == NULL)) {
        return 0;
    }

    shell_module = &shell_modules[module];
    for (i = 0; shell_module->commands[i].sc_cmd; i++) {
        cmd = &shell_module->commands[i];

        if (!strcmp(command, cmd->sc_cmd)) {

            if (!cmd->help || (!cmd->help->summary &&
                               !cmd->help->usage &&
                               !cmd->help->params)) {
                console_printf("(no help available)\n");
                return 0;
            }

            if (cmd->help->summary) {
                console_printf("Summary:\n");
                console_printf("%s\n", cmd->help->summary);
            }

            if (cmd->help->usage) {
                console_printf("Usage:\n");
                console_printf("%s\n", cmd->help->usage);
            }

            if (cmd->help->params) {
                console_printf("Parameters:\n");
                print_command_params(module, i);
            }

            return 0;
        }
    }

    console_printf("Unrecognized command: %s\n", argv[0]);
    return 0;
}

static void
print_modules(void)
{
    int module;

    for (module = 0; module < num_of_shell_entities; module++) {
        console_printf("%s\n", shell_modules[module].name);
    }
}

static void
print_module_commands(const int module)
{
    const struct shell_module *shell_module = &shell_modules[module];
    int i;

    console_printf("help\n");

    for (i = 0; shell_module->commands[i].sc_cmd; i++) {
        console_printf("%-30s", shell_module->commands[i].sc_cmd);
        if (shell_module->commands[i].help &&
            shell_module->commands[i].help->summary) {
        console_printf("%s", shell_module->commands[i].help->summary);
        }
        console_printf("\n");
    }
}

static int
show_help(int argc, char *argv[])
{
    int module;

    /* help per command */
    if ((argc > 2) || ((default_module != -1) && (argc == 2))) {
        return show_cmd_help(&argv[1]);
    }

    /* help per module */
    if ((argc == 2) || ((default_module != -1) && (argc == 1))) {
        if (default_module == -1) {
            module = get_destination_module(argv[1], -1);
            if (module == -1) {
                console_printf("Illegal module %s\n", argv[1]);
                return 0;
            }
        } else {
            module = default_module;
        }

        print_module_commands(module);
    } else { /* help for all entities */
        console_printf("Available modules:\n");
        print_modules();
        console_printf("To select a module, enter 'select <module name>'.\n");
    }

    return 0;
}

static int
set_default_module(const char *name)
{
    int module;

    module = get_destination_module(name, -1);

    if (module == -1) {
        console_printf("Illegal module %s, default is not changed\n", name);
        return -1;
    }

    default_module = module;

    return 0;
}

static int
select_module(int argc, char *argv[])
{
    if (argc == 1) {
        default_module = -1;
    } else {
        set_default_module(argv[1]);
    }

    return 0;
}

static shell_cmd_func_t
get_cb(int argc, char *argv[])
{
    const char *first_string = argv[0];
    int module = -1;
    const struct shell_module *shell_module;
    const char *command;
    int i;

    if (!first_string || first_string[0] == '\0') {
        console_printf("Illegal parameter\n");
        return NULL;
    }

    if (!strcmp(first_string, "help")) {
        return show_help;
    }

    if (!strcmp(first_string, "select")) {
        return select_module;
    }

    if ((argc == 1) && (default_module == -1)) {
        console_printf("Missing parameter\n");
        return NULL;
    }

    command = get_command_and_module(argv, &module);
    if ((module == -1) || (command == NULL)) {
        return NULL;
    }

    shell_module = &shell_modules[module];
    for (i = 0; shell_module->commands[i].sc_cmd; i++) {
        if (!strcmp(command, shell_module->commands[i].sc_cmd)) {
            return shell_module->commands[i].sc_cmd_func;
        }
    }

    return NULL;
}

static void
shell_process_command(char *line)
{
    char *argv[MYNEWT_VAL(SHELL_CMD_ARGC_MAX) + 1];
    shell_cmd_func_t sc_cmd_func;
    size_t argc_offset = 0;
    size_t argc;

    argc = line2argv(line, argv, MYNEWT_VAL(SHELL_CMD_ARGC_MAX) + 1);
    if (!argc) {
        print_prompt();
        return;
    }

    sc_cmd_func = get_cb(argc, argv);
    if (!sc_cmd_func) {
        if (app_cmd_handler != NULL) {
            sc_cmd_func = app_cmd_handler;
        } else {
            console_printf("Unrecognized command: %s\n", argv[0]);
            console_printf("Type 'help' for list of available commands\n");
            print_prompt();
            return;
        }
    }

    /* Allow invoking a cmd with module name as a prefix; a command should
     * not know how it was invoked (with or without prefix)
     */
    if (default_module == -1 && sc_cmd_func != select_module &&
        sc_cmd_func != show_help) {
        argc_offset = 1;
    }

    /* Execute callback with arguments */
    if (sc_cmd_func(argc - argc_offset, &argv[argc_offset]) < 0) {
        show_cmd_help(argv);
    }

    print_prompt();
}

#if MYNEWT_VAL(SHELL_NEWTMGR)
static void
shell_process_nlip_line(char *shell_line)
{
    size_t shell_line_len;

    shell_line_len = strlen(shell_line);
    if (shell_line_len > 2) {
        if (shell_line[0] == SHELL_NLIP_PKT_START1 &&
                shell_line[1] == SHELL_NLIP_PKT_START2) {
            shell_nlip_clear_pkt();
            shell_nlip_process(&shell_line[2], shell_line_len - 2);
        } else if (shell_line[0] == SHELL_NLIP_DATA_START1 &&
                shell_line[1] == SHELL_NLIP_DATA_START2) {
            shell_nlip_process(&shell_line[2], shell_line_len - 2);
        } else {
            shell_process_command(shell_line);
        }
    } else {
        shell_process_command(shell_line);
    }
}
#endif

static void
shell(struct os_event *ev)
{
    struct console_input *cmd;

    if (!ev) {
        print_prompt();
        return;
    }

    cmd = ev->ev_arg;
    if (!cmd) {
        print_prompt();
        return;
    }

#if MYNEWT_VAL(SHELL_NEWTMGR)
    shell_process_nlip_line(cmd->line);
#else
    shell_process_command(cmd->line);
#endif

    console_line_event_put(ev);
}

#if MYNEWT_VAL(SHELL_COMPLETION)
static int
get_command_from_module(const char *command, int len, int module)
{
    int i;
    const struct shell_module *shell_module;

    shell_module = &shell_modules[module];
    for (i = 0; shell_module->commands[i].sc_cmd; i++) {

        if (strlen(shell_module->commands[i].sc_cmd) != len) {
            continue;
        }

        if (!strncmp(command, shell_module->commands[i].sc_cmd, len)) {
            return i;
        }
    }
    return -1;
}

static int
get_token(char **cur, int *null_terminated)
{
    char *str = *cur;

    *null_terminated = 0;
    /* remove ' ' at the beginning */
    while (*str && *str == ' ') {
        str++;
    }

    if (*str == '\0') {
        *null_terminated = 1;
        return 0;
    }

    *cur = str;
    str = strchr(str, ' ');

    if (str == NULL) {
        *null_terminated = 1;
        return strlen(*cur);
    }

    return str - *cur;
}

static int
get_last_token(char **cur)
{
    *cur = strrchr(*cur, ' ');
    if (*cur == NULL) {
        return 0;
    }
    (*cur)++;
    return strlen(*cur);
}

static void
complete_param(char *line, const char *param_prefix,
               int param_len, int module_idx, int command_idx,
               console_append_char_cb append_char)
{
    const char *first_match = NULL;
    int i, j, common_chars = -1;
    const struct shell_cmd *command;

    command = &shell_modules[module_idx].commands[command_idx];

    if (!(command->help && command->help->params)) {
        return;
    }

    for (i = 0; command->help->params[i].param_name; i++) {

        if (strncmp(param_prefix,
            command->help->params[i].param_name, param_len)) {
            continue;
        }

        if (!first_match) {
            first_match = command->help->params[i].param_name;
            continue;
        }

        /* more commands match, print first match */
        if (first_match && (common_chars < 0)) {
            console_printf("\n");
            console_printf("%s\n", first_match);
            common_chars = strlen(first_match);
        }

        /* cut common part of matching names */
        for (j = 0; j < common_chars; j++) {
            if (first_match[j] != command->help->params[i].param_name[j]) {
                break;
            }
        }

        common_chars = j;

        console_printf("%s\n", command->help->params[i].param_name);
    }

    /* no match, do nothing */
    if (!first_match) {
        return;
    }

    if (common_chars >= 0) {
        /* multiple match, restore prompt */
        print_prompt();
        console_printf("%s", line);
    } else {
        common_chars = strlen(first_match);
    }

    /* complete common part */
    for (i = param_len; i < common_chars; i++) {
        if (!append_char(line, first_match[i])) {
            return;
        }
    }
}

static void
complete_command(char *line, char *command_prefix,
                 int command_len, int module_idx,
                 console_append_char_cb append_char)
{
    const char *first_match = NULL;
    int i, j, common_chars = -1, space = 0;
    const struct shell_module *module;

    module = &shell_modules[module_idx];

    for (i = 0; module->commands[i].sc_cmd; i++) {
        if (strncmp(command_prefix,
            module->commands[i].sc_cmd, command_len)) {
            continue;
        }

        if (!first_match) {
            first_match = module->commands[i].sc_cmd;
            continue;
        }

        /* more commands match, print first match */
        if (first_match && (common_chars < 0)) {
            console_printf("\n");
            console_printf("%s\n", first_match);
            common_chars = strlen(first_match);
        }

        /* cut common part of matching names */
        for (j = 0; j < common_chars; j++) {
            if (first_match[j] != module->commands[i].sc_cmd[j]) {
                break;
            }
        }

        common_chars = j;

        console_printf("%s\n", module->commands[i].sc_cmd);
    }

    /* no match, do nothing */
    if (!first_match) {
        return;
    }

    if (common_chars >= 0) {
        /* multiple match, restore prompt */
        print_prompt();
        console_printf("%s", line);
    } else {
        common_chars = strlen(first_match);
        space = 1;
    }

    /* complete common part */
    for (i = command_len; i < common_chars; i++) {
        if (!append_char(line, first_match[i])) {
            return;
        }
    }

    /* for convenience add space after command */
    if (space) {
        append_char(line, ' ');
    }
}

static void
complete_module(char *line, char *module_prefix,
                int module_len, console_append_char_cb append_char)
{
    int i, j;
    const char *first_match = NULL;
    int common_chars = -1, space = 0;

    if (!module_len) {
        console_printf("\n");
        for (i = 0; i < num_of_shell_entities; i++) {
            console_printf("%s\n", shell_modules[i].name);
        }
        print_prompt();
        console_printf("%s", line);
        return;
    }

    for (i = 0; i < num_of_shell_entities; i++) {

        if (strncmp(module_prefix,
                     shell_modules[i].name,
                     module_len)) {
            continue;
        }

        if (!first_match) {
            first_match = shell_modules[i].name;
            continue;
        }

        /* more commands match, print first match */
        if (first_match && (common_chars < 0)) {
            console_printf("\n");
            console_printf("%s\n", first_match);
            common_chars = strlen(first_match);
        }

        /* cut common part of matching names */
        for (j = 0; j < common_chars; j++) {
            if (first_match[j] != shell_modules[i].name[j]) {
                break;
            }
        }

        common_chars = j;

        console_printf("%s\n", shell_modules[i].name);
    }

    /* no match, do nothing */
    if (!first_match) {
        return;
    }

    if (common_chars >= 0) {
        /* multiple match, restore prompt */
        print_prompt();
        console_printf("%s", line);
    } else {
        common_chars = strlen(first_match);
        space = 1;
    }

    /* complete common part */
    for (i = module_len; i < common_chars; i++) {
        if (!append_char(line, first_match[i])) {
            return;
        }
    }

    /* for convenience add space after command */
    if (space) {
        append_char(line, ' ');
    }
}

static void
complete_select(char *line, char *cur,
                int tok_len, console_append_char_cb append_char)
{
    int null_terminated = 0;

    cur += tok_len + 1;
    tok_len = get_token(&cur, &null_terminated);
    if (tok_len == 0) {
        if (default_module != -1) {
            return;
        }
        console_printf("\n");
        print_modules();
        print_prompt();
        console_printf("%s", line);
        return;
    }

    if (null_terminated) {
        if (default_module == -1) {
            complete_module(line, cur, tok_len, append_char);
        }
    }
}

static void
completion(char *line, console_append_char_cb append_char)
{
    char *cur;
    int tok_len;
    int module, command;
    int null_terminated = 0;

    /*
     * line to completion is not ended by '\0' as the line that gets from
     * os_eventq_get function
     */
    if (!append_char(line, '\0')) {
        return;
    }

    cur = line;
    tok_len = get_token(&cur, &null_terminated);

    /* empty token - print options */
    if (tok_len == 0) {
        console_printf("\n");
        if (default_module == -1) {
            print_modules();
        } else {
            print_module_commands(default_module);
        }
        print_prompt();
        console_printf("%s", line);
        return;
    }

    /* token can be completed */
    if (null_terminated) {
        if (default_module == -1) {
            complete_module(line, cur, tok_len, append_char);
            return;
        }
        complete_command(line, cur, tok_len,
                         default_module, append_char);
        return;
    }

    if (strncmp("select", cur, tok_len) == 0) {
        complete_select(line, cur, tok_len, append_char);
        return;
    }

    if (default_module != -1) {
        module = default_module;
    } else {
        module = get_destination_module(cur, tok_len);

        if (module == -1) {
            return;
        }

        cur += tok_len + 1;
        tok_len = get_token(&cur, &null_terminated);

        if (tok_len == 0) {
            console_printf("\n");
            print_module_commands(module);
            print_prompt();
            console_printf("%s", line);
            return;
        }

        if (null_terminated) {
            complete_command(line, cur, tok_len,
                             module, append_char);
            return;
        }
    }

    command = get_command_from_module(cur, tok_len, module);
    if (command == -1) {
        return;
    }

    cur += tok_len;
    tok_len = get_last_token(&cur);
    if (tok_len == 0) {
        console_printf("\n");
        print_command_params(module, command);
        print_prompt();
        console_printf("%s", line);
        return;
    }
    complete_param(line, cur, tok_len,
                   module, command, append_char);
    return;
}
#endif /* MYNEWT_VAL(SHELL_COMPLETION) */

void
shell_register_app_cmd_handler(shell_cmd_func_t handler)
{
    app_cmd_handler = handler;
}

void
shell_register_prompt_handler(shell_prompt_function_t handler)
{
    app_prompt_handler = handler;
}

void
shell_register_default_module(const char *name)
{
    int result = set_default_module(name);

    if (result != -1) {
        console_printf("\n");
        print_prompt();
    }
}

static void
shell_avail_queue_init(void)
{
    int i;

    for (i = 0; i < MYNEWT_VAL(SHELL_MAX_CMD_QUEUED); i++) {
        shell_console_ev[i].ev_cb = shell;
        shell_console_ev[i].ev_arg = &buf[i];
        console_line_event_put(&shell_console_ev[i]);
    }
}

int
shell_register(const char *module_name, const struct shell_cmd *commands)
{
    if (num_of_shell_entities >= MYNEWT_VAL(SHELL_MAX_MODULES)) {
        console_printf("Max number of modules reached\n");
        assert(0);
    }

    shell_modules[num_of_shell_entities].name = module_name;
    shell_modules[num_of_shell_entities].commands = commands;
    ++num_of_shell_entities;

    return 0;
}

#if MYNEWT_VAL(SHELL_COMPAT)
#define SHELL_COMPAT_MODULE_NAME "compat"
static struct shell_cmd compat_commands[MYNEWT_VAL(SHELL_MAX_COMPAT_COMMANDS) + 1];
static int num_compat_commands;
static int module_registered;

int
shell_cmd_register(const struct shell_cmd *sc)
{
    if (num_compat_commands >= MYNEWT_VAL(SHELL_MAX_COMPAT_COMMANDS)) {
        console_printf("Max number of compat commands reached\n");
        assert(0);
    }

    if (!module_registered) {
        shell_register(SHELL_COMPAT_MODULE_NAME, compat_commands);
        set_default_module(SHELL_COMPAT_MODULE_NAME);
        module_registered = 1;
    }

    compat_commands[num_compat_commands].sc_cmd = sc->sc_cmd;
    compat_commands[num_compat_commands].sc_cmd_func = sc->sc_cmd_func;
#if MYNEWT_VAL(SHELL_CMD_HELP)
    compat_commands[num_compat_commands].help = sc->help;
#endif
    ++num_compat_commands;
    return 0;
}
#endif

void
shell_init(void)
{
    /* Ensure this function only gets called by sysinit. */
    SYSINIT_ASSERT_ACTIVE();

#if !MYNEWT_VAL(SHELL_TASK)
    return;
#endif

    shell_avail_queue_init();
    shell_evq_set(os_eventq_dflt_get());

    prompt = SHELL_PROMPT;

#if MYNEWT_VAL(SHELL_NEWTMGR)
    shell_nlip_init();
#endif

#if MYNEWT_VAL(SHELL_COMPLETION)
    console_set_completion_cb(completion);
#endif

#if MYNEWT_VAL(SHELL_OS_MODULE)
    shell_os_register();
#endif
#if MYNEWT_VAL(SHELL_PROMPT_MODULE)
    shell_prompt_register();
#endif
}
