/*
 * ll_consolehandler.cpp
 *
 *  Created on: Nov 7, 2019
 *      Author: abody
 */

#include <f4ll/console_handler.h>
#include <f4ll/irq_lock.h>
#include <f4ll/str_util.h>

#include <cstring>

namespace f4ll {

console_handler::console_handler(USART_TypeDef *usart, DMA_TypeDef *dma, uint32_t stream_rx, uint32_t stream_tx)
    : usart_core(usart, dma, stream_rx, stream_tx)
{
}

void console_handler::receiver_idle(void) {}

void console_handler::transmission_complete(void)
{
    m_tx_buffer.consumed(m_in_flight_size);
    if (m_tx_buffer.commited()) {
        uint8_t const *chunk;
        m_tx_buffer.get_chunk(m_tx_buffer.size(), chunk, m_in_flight_size);
        if (m_in_flight_size) {
            setup_transmit(chunk, m_in_flight_size);
        }
    } else {
        m_in_flight_size = 0;
    }
}

void console_handler::framing_error(void) {}

void console_handler::overrun(void) {}

void console_handler::rx_dma_transfer_complete(void) {}

void console_handler::rx_dma_half_transfer(void) {}

void console_handler::rx_dma_error(dma_helper::dma_error_type reason)
{
    (void)reason;
}

void console_handler::tx_dma_transfer_complete(void)
{
    LL_USART_EnableIT_TC(m_usart);
    LL_DMA_DisableStream(m_tx_dma.get_dma(), m_tx_dma.get_stream());
}

void console_handler::tx_dma_half_transfer(void) {}

void console_handler::tx_dma_error(dma_helper::dma_error_type reason)
{
    (void)reason;
}

size_t console_handler::append(char const *s)
{
    size_t len = strlen(s);
    if (!len) {
        return 0;
    }
    return len - m_tx_buffer.put(reinterpret_cast<uint8_t const *>(s), len);
}

void console_handler::flush()
{
    if (!m_tx_buffer.uncommited()) {
        return;
    }
    m_tx_buffer.commit();

    if (m_in_flight_size) {
        return;
    }

    uint8_t const *chunk;
    m_tx_buffer.get_chunk(m_tx_buffer.size(), chunk, m_in_flight_size);
    if (m_in_flight_size) {
        setup_transmit(chunk, m_in_flight_size);
    }
}

void console_handler::print(char const *s)
{
    append(s);
    flush();
}

} /* namespace f4ll */
