/*
 * This file is part of the EasyLogger Library.
 *
 * Created on: 2015-04-28
 * Modified By Pophu 2023-08-22
 */

#if 1

#include <stdio.h>
#include <elog.h>
#include "main.h"
#include "cmsis_os2.h"
#include "FreeRTOSConfig.h"
#include "usart.h"
// #include "platform.h"

// extern UART_HandleTypeDef huart1;
extern void elog_entry(void *para);
extern void Init_Logger();
  
#define pLogMenuHuart  &huart1 

/* **************** 信号量  SemaPhore  **************** */
osSemaphoreId_t elog_lockHandle;
const osSemaphoreAttr_t elog_lock_attributes = {
    .name = "elog_lock"};

osSemaphoreId_t elog_dma_lockHandle;
const osSemaphoreAttr_t elog_dma_lock_attributes = {
    .name = "elog_dma_lock"};

#ifdef ELOG_ASYNC_OUTPUT_ENABLE
osSemaphoreId_t elog_asyncHandle;
const osSemaphoreAttr_t elog_async_attributes = {
    .name = "elog_async"};
#endif

/* **************** Easylogger 任务  **************** */
#ifdef ELOG_ASYNC_OUTPUT_ENABLE
osThreadId_t elogHandle;
const osThreadAttr_t elog_attributes = {
    .name = "elog",
    .stack_size = 256*4,
    .priority = (osPriority_t)osPriorityLow,
};
#endif

// extern osSemaphoreId_t elog_lockHandle;
// extern osSemaphoreId_t elog_asyncHandle;
// extern osSemaphoreId_t elog_dma_lockHandle;
// extern osSemaphoreId_t elog_menuHandle;

volatile uint16_t asyncflag = 0;

/**
 * EasyLogger port initialize
 *
 * @return result
 */
ElogErrCode elog_port_init(void)
{
    ElogErrCode result = ELOG_NO_ERR;

    // osSemaphoreRelease(elog_lockHandle);
    // osSemaphoreRelease(elog_dma_lockHandle);

    return result;
}

/**
 * EasyLogger port deinitialize
 *
 */
void elog_port_deinit(void)
{

    /* add your code here */
}

/**
 * output log port interface
 *
 * @param log output of log
 * @param size log size
 */
void elog_port_output(const char *log, size_t size)
{

    /* add your code here */
// #ifdef LOG_MENU_485
//     log_menu_send_enable();
// #endif
    HAL_UART_Transmit_DMA(pLogMenuHuart, (uint8_t *) log, size);
    // HAL_UART_Transmit(&huart1, (uint8_t *) log, size,0xFF);
    // printf((uint8_t *)log, size);
}

/**
 * output lock
 */
void elog_port_output_lock(void)
{

    /* add your code here */
    osSemaphoreAcquire(elog_lockHandle, osWaitForever);
 
}

/**
 * output unlock
 */
void elog_port_output_unlock(void)
{

    /* add your code here */
    osSemaphoreRelease(elog_lockHandle);
 
}

/**
 * get current time interface
 *
 * @return current time
 */
const char *elog_port_get_time(void)
{

    /* add your code here */
    static char cur_system_time[16] = "";
    snprintf(cur_system_time, 16, "%lu", osKernelGetTickCount());
    return cur_system_time;
}

/**
 * get current process name interface
 *
 * @return current process name
 */
const char *elog_port_get_p_info(void)
{

    /* add your code here */
    return "";
}

/**
 * get current thread name interface
 *
 * @return current thread name
 */
const char *elog_port_get_t_info(void)
{

    /* add your code here */
    return "";
}

#ifdef ELOG_ASYNC_OUTPUT_ENABLE
void elog_async_output_notice(void)
{
        asyncflag++;
    osSemaphoreRelease(elog_asyncHandle);
}

/*  借助串口发送完成中断，形成闭环，否则会阻塞 */
void elog_entry(void *para)
{
    size_t get_log_size = 0;
    static char poll_get_buf[ELOG_LINE_BUF_SIZE - 4];

    if (elog_port_init() != ELOG_NO_ERR)
    {
        goto fail;
    }

    while (1)
    {
  
        if (osOK ==  osSemaphoreAcquire(elog_asyncHandle, osWaitForever))
        {
            // printf(" elog_asyncHandle acq ok... \r\n");
            while (1)
            {
                if (osOK ==  osSemaphoreAcquire(elog_dma_lockHandle, osWaitForever))
                {
                    asyncflag--;
                    get_log_size = elog_async_get_line_log(poll_get_buf, sizeof(poll_get_buf));
                    if (get_log_size)
                    {
                        elog_port_output(poll_get_buf, get_log_size);
                    }
                    else
                    {
                        osSemaphoreRelease(elog_dma_lockHandle);
                        break;
                    }
                }
            }
        }

        // osDelay(10);
    }

    fail:
        osThreadExit();
}

#endif

void Init_Logger()
{
    elog_lockHandle = osSemaphoreNew(1, 1, &elog_lock_attributes);
    osSemaphoreRelease(elog_lockHandle);
 
#ifdef ELOG_ASYNC_OUTPUT_ENABLE
    elog_asyncHandle = osSemaphoreNew(1, 1, &elog_async_attributes);
    elog_dma_lockHandle = osSemaphoreNew(1, 1, &elog_dma_lock_attributes);
    osSemaphoreRelease(elog_dma_lockHandle);
#endif
 
    elog_init();
    // elog_set_filter_lvl(ELOG_LVL_INFO);
    elog_set_output_enabled(ENABLE);
#ifdef ELOG_BUF_OUTPUT_ENABLE
    elog_buf_enabled(ENABLE);
#endif
#ifdef ELOG_ASYNC_OUTPUT_ENABLE
    elog_async_enabled(ENABLE);
#endif
    elog_set_text_color_enabled(ENABLE);
    elog_output_lock_enabled(ENABLE);
    /* set EasyLogger log format */
    elog_set_fmt(ELOG_LVL_ASSERT, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME | ELOG_FMT_FUNC | ELOG_FMT_LINE);
    elog_set_fmt(ELOG_LVL_ERROR, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME | ELOG_FMT_FUNC | ELOG_FMT_LINE);
    elog_set_fmt(ELOG_LVL_WARN, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME | ELOG_FMT_FUNC | ELOG_FMT_LINE);
    elog_set_fmt(ELOG_LVL_INFO, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME | ELOG_FMT_FUNC | ELOG_FMT_LINE);
    elog_set_fmt(ELOG_LVL_DEBUG, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME | ELOG_FMT_FUNC | ELOG_FMT_LINE);
    /* start EasyLogger */

    // elog_set_filter_tag("Modbus");
    elog_start();

#ifdef ELOG_ASYNC_OUTPUT_ENABLE
    elogHandle = osThreadNew(elog_entry, NULL, &elog_attributes);
#endif
}


#endif