/**
 * \file    cli_engine.h
 * \brief   Command line interface engine
 *
 * \par     Copyright (c) 2018 UWE Technologies Corp., Ltd. All Rights Reserved.
 * \author  James
 * \date    2018-03-17
 * \version 
 * 
 * \history 
 *  Date        Note
 *  2018-03-01  Original Creation
 * 
 */
 
#ifndef __CLI_ENGINE_H_
#define __CLI_ENGINE_H_


#include "types.h"
#include "arch.h"


#if CLI_ENABLED

#pragma pack(1)

/** \name  CLI module platform command definitions
 * \{ 
 */
#define CLI_INCLUDE_LINEEDIT        1     ///< included line edit
#define CLI_INCLUDE_HELP            1     ///< included help
#define CLI_INCLUDE_LOGOUT          1     ///< included logout
#define CLI_INCLUDE_RESET           1     ///< included reset
#define CLI_INCLUDE_VER             1     ///< included version
#define CLI_INCLUDE_REG             1     ///< included register control
#define CLI_INCLUDE_DM              1     ///< included display memory
#define CLI_INCLUDE_MM              1     ///< included modify memory
#define CLI_INCLUDE_GPIO            1     ///< included GPIO
#define CLI_INCLUDE_GPIO_CAP        1     ///< included GPIO IN CAPTURE
#define CLI_INCLUDE_ADC             1     ///< included ADC
#define CLI_INCLUDE_SPI             SPI_MODULE_ENABLED     ///< included SPI
#define CLI_INCLUDE_I2C             I2C_MODULE_ENABLED     ///< included I2C
#define CLI_INCLUDE_PWM             1     ///< included PWM
#define CLI_INCLUDE_WDT             1     ///< included WDT
#define CLI_INCLUDE_UART            1     ///< incluced UART
#define CLI_INCLUDE_SYS             1     ///< included system information
#define CLI_INCLUDE_CFG             1     ///< included system configuration
#define CLI_INCLUDE_UPGRADE         0     ///< included upgrade
#define CLI_INCLUDE_BIST            1     ///< included BIST
/** \} */

/** CLI enabled verbose help feature */
#define CLI_ENABLED_VERBOSE_HELP    1

/** CLI command list size */
#define CLI_CMD_LIST_ITEMS_MAX      25
#define CLI_CMD_LIST_ITEMS_VALID    (CLI_CMD_LIST_ITEMS_MAX-1)

/* 5 bytes are resered for prompt "UPD> " */
#define CLI_CMD_LINE_WIDTH          80
#define CLI_MAX_CMD_BYTES           75
#define CLI_MAX_ESC_BYTES           3

#define CLI_CMD_ARGCNT              8
#define CLI_CMD_HIS_MAX             2

#define CLI_CTLC                    0x03
#define CLI_BS                      0x08
#define CLI_NL                      0x0A
#define CLI_CR                      0x0D
#define CLI_ESC                     0x1B
#define CLI_BLKSPACE                0x20
#define CLI_STAR                    0x2A
#define CLI_OPEN_BRACKET            0x5B

#define CLI_VT100_UP                'A'
#define CLI_VT100_DOWN              'B'
#define CLI_VT100_RIGHT             'C'
#define CLI_VT100_LEFT              'D'

#define CLI_STR_TYPE_STR            0
#define CLI_STR_TYPE_PWD            1

#define CLI_PWD_STR_LEN             11
#define CLI_PWD_STR_MAX_LEN         32

/** CLI command execute result */
typedef enum CLI_CMD_RESULT_e
{
    CLI_CMD_SUCCESS,     ///< Command execute success
    CLI_CMD_FAILURE,     ///< Command execute failure
    CLI_CMD_PARAM_ERROR, ///< Command parameter error
    CLI_CMD_DENIED,      ///< Command execute denied
    CLI_CMD_NOT_FOUND,   ///< Command not found
    CLI_CMD_RESULT_MAX   ///< Maximal command result
} CLI_CMD_RESULT_t;

/** Command line table structure */
typedef struct CLI_CMD_LIST_s
{
    const char *command;         ///< Command string 
    const char * const *desc;           ///< Command description
    int  (*func)(int,char **);   ///< Function to be executed 
} CLI_CMD_LIST_t;

typedef struct CLI_CMD_INFO_s
{
	u8_t  cursor_pos;                     /* current cursor position */	
    u8_t  input_len;                      /* the length of input command */
    char  input_cmd[CLI_MAX_CMD_BYTES];   /* the current input command */
#if CLI_INCLUDE_LINEEDIT
    char  esc_buf[CLI_MAX_ESC_BYTES];  
    u8_t  esc_buf_pos;
    u8_t  his_pos;                    /* the current command position of history command list */
    char  his_cmd[CLI_CMD_HIS_MAX][CLI_MAX_CMD_BYTES];  /* History command list */
#endif
} CLI_CMD_INFO_t;

#pragma pack()

/** \brief Add cli command to global list
 *
 * \param command   Pointer to the command
 * \param desc      Pointer to the command description pointer
 * \param func      Command execute function
 * \return          0: FALSE, 1: TRUE
 */
int cli_cmd_list_add(const char *command, const char * const *desc, int (*func)(int,char **));

/** \brief Print SDK brand information
 *
 * \param copyright     With(1) or without(0) copyright print
 */
void cli_print_brand(bool_t copyright);

/** \brief display command verbose help 
 *
 * \param list          Command list
 * \param index         Command list index
 * \return              Execute result, TRUE or FALSE
 */
bool_t cli_show_verbose_help(CLI_CMD_LIST_t *list, int index);

/** \brief cli engine initialization
 *
 */
void cli_init(void);

/** \brief cli input handler
 *
 * \param input         Input charactor
 */
void cli_do_work(u8_t input);

#endif


#endif /* #ifndef __CLI_ENGINE_H_ */

