/* ****************************************************************************
 * File:      cli
 * Date:      9 Jul 2024
 * Author:    Andrew Levido
 *
 * Copyright 2024 Imbrius Pty Ltd - All Rights Reserved
 *
 *****************************************************************************/
#ifndef _cli_H
#define _cli_H

#ifdef __cplusplus
extern "C" {
#endif

/* Description -----------------------------------------------------------------
 * Command line interface using "embedded cli" from funbiscuit as the core. This
 * provides a simple cli with
 *  - auto-complete on commands (tab key to complete)
 *  - command history (up and down arrows)
 *  - run-time or start-up binding of commands
 *  - optional tokenisation of command line arguments
 *    > space separates args: command abc def     arg1 = abc, arg2 = def
 *    > quotes allow spaces : command "abc def"   arg1 = abc def
 *    > backslash escapes   : command ab\"d\\f    arg1 = ab"d\f
 *    > space optional with quoted args
 * 
 * cli.h/.c file is a wrapper function. The user must:
 * 
 *  1. Provide a "cli_putc" callback function that writes characters to the 
 *     selected output stream. 
 *  2. Arrange for the "cli_getc" function to be called to put characters
 *     received from the input stream into the cli input buffer
 *  3. Call "cli_init" once to start cli and register the cli_putc callback
 *  4. Register any command bindings by calling the "cli_register_command"
 *     function (this can happen any time after step 3) Default bindings are
 *     provided for clear screen (clear) and help (help)
 *  5. Call the "cli_process" function periodically to process cli events
 *  6. You can use the cli_write_line, cli_printf, cli_msg, cli_dbg, cli_wrn
 *     and cli_err functions once the cli is started, these will be ignored
 *     if it is not. 
 * 
 */

/* Includes ------------------------------------------------------------------*/

#include "embedded_cli.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/* Defines -------------------------------------------------------------------*/
#define CLI_USE_DEBUG
#define CLI_USE_WARNING
#define CLI_LARGE_BUFFER    __attribute__ ((section (".sdram")))
/* Typedefs & Enumerations ---------------------------------------------------*/

typedef struct {
  char * sub_command;
  char * sub_command_help;
} cli_sub_command_t;

typedef struct CliCommandBinding cli_cmd_binding_t;

/* Public Functions Declarations ---------------------------------------------*/

/** Initialise Command Line Interface
 * 
 * @param cli_putc   pointer to function to write  a char to the output stream
 * @returns true if successfully initialised, false if out of space
 */
bool cli_init(void (*cli_putc)(char c));

/** Function to put one char from input stream into CLI 
 * 
 * @param c       char to push into cli input buffer.
*/
void cli_getc(char c);

/** Process CLI commands
* Call regularly after cli_init() to process cli input buffer 
*/
void cli_process(void);

/** Register CLI command binding
 * 
 * @param cmd         command name string
 * @param help        command help string
 * @param tokenise    true to tokenise command arguments
 * @param callback    callback to handle the command
 * @returns true if successfully registerd, false if out of space
 */
bool cli_register_command(char* cmd, const char* help, bool tokenise, void(*callback)(char*args));

/** Retreive cli argument tokens 
*
* @param tokenised_string arg* passes as param to cli command callback (tokenise = true)
* @param pos              param position
* @returns                pointer to null-terminated token string or null if none
*/
char* cli_get_token(char *tokenised_string, uint16_t pos);

/** Write a string to the console
 *
 * Writes a string to the console. Strings longer than width 
 * are truncated. 
 */
void cli_write_line(char * string);

/** Write a formatted string to the console
 * 
 * Writes a "printf" style formatted string to the console. Linefeed
 * Appended Strings longer than width are truncated
 * 
 * @param format format string
 * @param ...    variable length argument string    
 */
void cli_printf(const char * fmt, ...);

/** Write a formatted string to the console
 * 
 * Writes a "printf" style formatted string to the console. The user must 
 * append \n\r if required. Strings longer than width are truncated
 * 
 * @param format format string
 * @param ...    variable length argument string    
 */
void cli_printf_no_lf(const char * fmt, ...);

/** Write message to the console
 * 
 * Writes a message string to the console. Prefixed by MSG: and 
 * followed by \n\r. Strings longer than width are truncated
 * 
 * @param str 	null-terminated string to write    
 */
void cli_msg(char * str);

/** Write warning to the console
 * 
 * Writes a message string to the console. Prefixed by WRN: and 
 * followed by \n\r. Strings longer than width are truncated
 * 
 * @param str 	null-terminated string to write    
 */
void cli_wrn(char * str);

/** Write error to the console
 * 
 * Writes a message string to the console. Prefixed by ERR: and 
 * followed by \n\r. Strings longer than width are truncated
 * 
 * @param str 	null-terminated string to write    
 */
void cli_err(char * str);

/** Write message to the console
 * 
 * Writes a message string to the console. Prefixed by DBG: and 
 * followed by \n\r. Strings longer than width are truncated
 * 
 * @param str 	null-terminated string to write    
 */
void cli_dbg(char * str);

#ifdef __cplusplus
}
#endif

#endif

/* End cli */