/*
 * app.h
 *
 *  Created on: Aug 29, 2019
 *      Author: abody
 */

#pragma once

#include <FreeRTOS.h>
#include <inttypes.h>
#include <portmacro.h>

#ifdef __cplusplus
#include <f4ll/console_handler.h>
#include <task.h>
#include <thread_safe_console_output.h>

class app : public f4ll::initialized_singleton<app>, f4ll::console_handler::iconsole_input
{
    friend class f4ll::initialized_singleton<app>;

private:
    app(void const *param);

public:
    __attribute__((noreturn)) void main();
    void input_available(f4ll::console_handler::size_type len) override;

private:
    static void cli_task_dispatch(void *param) { static_cast<app *>(param)->cli_task(); }
    __attribute__((noreturn)) void cli_task();
    static constexpr size_t const CLI_TASK_STACK_LEN = 128;
    StackType_t m_cli_task_stack[CLI_TASK_STACK_LEN];
    StaticTask_t m_cli_task_buffer;
    TaskHandle_t m_cli_task_handle;

    f4ll::console_handler &m_con;
    static constexpr size_t const TXBUF_LEN = 128;
    static constexpr size_t const RXBUF_LEN = 32;
    uint8_t m_tx_buf_mem[TXBUF_LEN];
    uint8_t m_rx_buf_mem[RXBUF_LEN];

    thread_safe_console_output m_safe_conout;

    void queue_ts();
};

extern "C" {
#endif //   __cplusplus

void app_main(void const *param) __attribute__((noreturn));

#ifdef __cplusplus
} //	extern "C" {
#endif //   __cplusplus
