#ifndef CLI_PROTOCOL_H
#define CLI_PROTOCOL_H

#include "cli_protocol_cfg.h"
#include "l_macro_types.h"


typedef enum {
    CLI_CMD_OPEN        = 0x00U,    // T00 - открыть соединение (с паролем)
    CLI_CMD_CLOSE       = 0x01U,    // T01 - закрыть соединение
    CLI_CMD_ECHO        = 0x02U,    // T02 - проверка соединения (ping) 
    CLI_CMD_GET_INFO    = 0x03U,    // T03 - получить информацию об устройстве (имя, серийный, версия)
    
} cli_cmd_t;


// Коды ошибок хэндла команды
typedef enum {
    CLI_HND_OK_RX = 0, // Прием данных успешен
    CLI_HND_OK_TX,     // Хэндл подготовил ответ для передачи
    CLI_HND_ERR_ARG,   // Неверный формат или значение аргумента
    CLI_HND_ERR_INT,   // Ошибка выполнения
    CLI_HND_BUSY,      // Хэндл пока не может быть выполнен
} cli_hnd_err_t;


// Структура с информацией об устройстве
typedef struct {
    char name[16];      // Имя устройства (ASCII, до 15 символа + \0)
    char serial[16];    // Серийный номер (ASCII, до 15 символов + \0)
    char version[16];   // Версия команд CLI (ASCII, до 15 символов + \0)
} cli_device_info_t;


// Прототип функции-обработчика команды
//  - data Указатель на сырые данные команды (после board_id)
//  - len  Длина данных в байтах
// Выозвращает код ошибки (cli_hnd_err_t)
typedef i8 (*cli_cmd_handler_t)(const u8* data, u8 len);


// Структура для регистрации пользовательской команды
typedef struct {
    u8 code;                    // Код команды (0x00–0xFF)
    cli_cmd_handler_t handler;  // Указатель на функцию-обработчик
} cli_command_t;


//************************************ Публичные функции ****************************************************

//! @brief Инициализация протокола CLI
//! @return ERR_OK при успехе, иначе код ошибки
fun_res_t cli_protocol_init(void);


//! @brief Деинициализация протокола CLI
//! @return ERR_OK при успехе, иначе код ошибки
fun_res_t cli_protocol_deinit(void);


//! @brief Основной цикл обработки (вызывать в главном цикле программы)
void cli_protocol_process(void);


//! @brief Отправка строки через UART (с ожиданием завершения передачи)
//! @param str Указатель на нуль-терминированную строку
void cli_prepare_tx_data(u8* hex_data, u8 size);


//! @brief Установка информации об устройстве
//! @param name      Имя устройства (до 15 символа)
//! @param serial    Серийный номер (до 15 символов)
//! @param ver       Версия ПО (до 15 символов)
//! @return ERR_OK при успехе
fun_res_t cli_protocol_set_device_info(const char* name, const char* serial, const char* ver);


//! @brief Регистрация новой команды
//! @param cmd Указатель на структуру с кодом и обработчиком
//! @return ERR_OK при успехе, ERR_INVALID_ARGUMENT – неверные параметры,
//!         ERR_RUNTIME_ERROR – команда уже зарегистрирована
fun_res_t cli_register_command(const cli_command_t* cmd);


//! @brief Обнулить регистрацию указанной команды
//! @param cmd Код команды
void cli_unregister_command(u8 code);


#endif  