#include "app_cmd.h"
#include "myBase.h"
#include "myCmd.h"
#include "myLog.h"
#include "mySystem.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define MAX_ARGC 16


LOCAL void cmd_recv()
{
    char *line = linenoise("cmd > ");
    if(line == NULL)
    {
        return;
    }

    if(strlen(line) == 0)
    {
        free(line);
        return;
    }

    linenoiseHistoryAdd(line);


    char *orig_line = strdup(line);
    if(orig_line == NULL)
    {
        free(line);
        return;
    }

    char *argv[MAX_ARGC];
    int argc = 0;
    char *p = strtok(line, " \t");
    while(p != NULL && argc < MAX_ARGC)
    {
        argv[argc++] = p;
        p = strtok(NULL, " \t");
    }

    if(argc == 0)
    {
        free(orig_line);
        free(line);
        return;
    }

    stru_cmd *p_cmd = cmd_find(argv[0]);
    if(NULL == p_cmd)
    {
        if(strcmp(argv[0], "cd") == 0)
        {
            const char *path = (argc >= 2) ? argv[1] : getenv("HOME");
            if(path == NULL || chdir(path) != 0)
            {
                LOG_E("cd failed: %s", path ? path : "(null)");
            }
            free(orig_line);
            free(line);
            return;
        }

        // 如果不是内部命令，则尝试执行 Linux shell 命令
        if(system(orig_line) != 0)
        {
            LOG_E("shell command failed: %s", orig_line);
        }
        free(orig_line);
        free(line);
        return;
    }
    p_cmd->func(argc, argv);

    free(orig_line);
    free(line);
}

int app_cmd_init1(void *arg)
{
    lineniseSetCompletionCallback(cmd_complete);

    return 0;
}

int app_cmd_init2(void *arg)
{
    return 0;
}

void *app_cmd(void *arg)
{
    if(NULL == arg)
    {
        LOG_E("app_cmd arg null");
        return NULL;
    }

    stru_app *p_app = (stru_app *)arg;

    uint32_t event;

    while(1)
    {
        task_event_recv(p_app->p_event, 
            EV_TIMER1 | EV_TIMER2 | EV_TIMER3, 
            TASK_EVENT_FLAG_OR | TASK_EVENT_FLAG_CLEAR, 
            TASK_EVENT_WAIT_FOREVER, 
            &event);

        if(event & EV_TIMER1)
        {
            cmd_recv();
        }

        if(event & EV_TIMER2)
        {
            ;
        }

        if(event & EV_TIMER3)
        {
            p_app->run_cnt++;
        }
    }


    return NULL;
}