#include <stdint.h>
#include "Protocol_User.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_bt.h"

#include "esp_gap_ble_api.h"
#include "esp_gatts_api.h"
#include "esp_bt_main.h"
#include "gatts_table_creat_demo.h"
#include "esp_gatt_common_api.h"

#include "esp_mac.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "driver/uart.h"
#include "string.h"
#include "driver/gpio.h"
#include "MCU_Core_Protocol.h"
#include "Protocol_Lib.h"
#include "app_Ble_User.h"
#include "app_BT_User.h"

#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>

#include "main_user.h"



#define TAG "Prot_User"
Protocol_User_Ctrl_Struct Prot_User;



#define UART_TX_MAX_DEPTH 1024UL          //(2 * 1024UL)    // 4K
#define UART_RX_MAX_DEPTH (2 * 1024UL)    // 4K
#define UART_DATA_BUF_LEN (2 * 1024UL)    // 4K
//extern void OTA_IC_To_Master( uint8_t len);
typedef struct
{
    Protocol_uint32_t read_pos;
    Protocol_uint32_t write_pos;
    Protocol_uint8_t  Rx_Buffer [ UART_RX_MAX_DEPTH ];
} UARTRxBuf_t;

typedef struct
{
    Protocol_uint32_t read_pos;
    Protocol_uint32_t write_pos;
    Protocol_uint8_t  Tx_Buffer [ UART_TX_MAX_DEPTH ];
} UARTTxBuf_t;

static UARTRxBuf_t      UARTRxBuf;
static UARTTxBuf_t      UARTTxBuf;
static Protocol_uint8_t UsartDataBuf [ 256 ];
static Protocol_uint8_t mDataBufPtr [ UART_DATA_BUF_LEN ];

static Protocol_uint8_t  Protocol_OpenUart(void);
static Protocol_uint32_t Protocol_UartRead(Protocol_uint8_t *pData, Protocol_uint32_t u32Len);
static Protocol_uint32_t Protocol_UartSend(const Protocol_uint8_t *pData, Protocol_uint32_t u32Len);
static void              Protocol_UartHandle(const Protocol_Data_t *pData);

void Protocol_KL30_Wakeup_Init(void)
{
    Protocol_Func_t pFunc;

    pFunc.UARTOpen_Cbk        = Protocol_OpenUart;
    pFunc.UARTSend_Cbk        = Protocol_UartSend;
    pFunc.UARTRead_Cbk        = Protocol_UartRead;
    pFunc.UARTClose_Cbk       = Protocol_NULL;
    pFunc.ProcParseCbk        = Protocol_NULL;
    pFunc.ProtocolSetData_Cbk = Protocol_UartHandle;
    UARTTxBuf.read_pos        = 0;
    UARTTxBuf.write_pos       = 0;
    UARTRxBuf.read_pos        = 0;
    UARTRxBuf.write_pos       = 0;

    Protocol_Init(mDataBufPtr, UART_DATA_BUF_LEN, &pFunc);
}


void Protocol_Send_Service(void)
{
    Protocol_uint32_t i       = 0u;
    Protocol_uint32_t DataLen = 0u;
    Protocol_uint32_t SendLen = 0u;


    if ( UARTTxBuf.write_pos == UARTTxBuf.read_pos )
    {
        return;
    }

    if ( UARTTxBuf.write_pos > UARTTxBuf.read_pos )
    {
        DataLen = UARTTxBuf.write_pos - UARTTxBuf.read_pos;
    }
    else
    {
        DataLen = UART_TX_MAX_DEPTH - (UARTTxBuf.read_pos - UARTTxBuf.write_pos);
    }

    if ( DataLen > 255 )
    {
        SendLen = 255;
    }
    else
    {
        SendLen = DataLen;
    }

    for ( i = 0u; i < SendLen; i++ )
    {
        UsartDataBuf [ i ] = UARTTxBuf.Tx_Buffer [ UARTTxBuf.read_pos ];
        UARTTxBuf.read_pos = (UARTTxBuf.read_pos + 1) % UART_TX_MAX_DEPTH;
    }


    bsp_Uart_Send_Data(UsartDataBuf, SendLen);

}

static Protocol_uint8_t Protocol_OpenUart(void)
{
#if 0
    UART_Channel_Config_st_t loc_config;

    loc_config.u32UARTChEn            = 1;
    loc_config.u32UARTbps             = 115200;
    loc_config.pfnUARTConfirmCallBack = Protocol_NULL;
    loc_config.pfnUARTReadMsgCallBack = UART_Put;

    UART_Init(UART_RLIN31, &loc_config);
#endif
    return 1;
}

static Protocol_uint32_t Protocol_UartRead(Protocol_uint8_t *pData, Protocol_uint32_t len)
{
    Protocol_uint32_t i       = 0;
    Protocol_uint32_t DataLen = 0u;
    Protocol_uint32_t ReadLen = 0u;

    if ( UARTRxBuf.write_pos == UARTRxBuf.read_pos )
    {
        return 0;    //队列空
    }

    if ( UARTRxBuf.write_pos > UARTRxBuf.read_pos )
    {
        DataLen = UARTRxBuf.write_pos - UARTRxBuf.read_pos;
    }
    else
    {
        DataLen = UART_RX_MAX_DEPTH - (UARTRxBuf.read_pos - UARTRxBuf.write_pos);
    }

    if ( len > DataLen )
    {
        ReadLen = DataLen;
    }
    else
    {
        ReadLen = len;
    }

    for ( i = 0u; i < ReadLen; i++ )
    {
        pData [ i ]        = UARTRxBuf.Rx_Buffer [ UARTRxBuf.read_pos ];
        UARTRxBuf.read_pos = (UARTRxBuf.read_pos + 1) % UART_RX_MAX_DEPTH;
    }

    return ReadLen;
}

static Protocol_uint32_t Protocol_UartSend(const Protocol_uint8_t *pData, Protocol_uint32_t u32Len)
{
    Protocol_uint32_t i         = 0;
    Protocol_uint32_t RemainLen = 0u;

    if ( UARTTxBuf.write_pos >= UARTTxBuf.read_pos )
    {
        RemainLen = UART_TX_MAX_DEPTH - (UARTTxBuf.write_pos - UARTTxBuf.read_pos);
    }
    else
    {
        RemainLen = UARTTxBuf.read_pos - UARTTxBuf.write_pos;
    }

    if ( u32Len > RemainLen )
    {
        return 1;    //队列已满，无法插入队列
    }

    for ( i = 0; i < u32Len; i++ )
    {
        UARTTxBuf.Tx_Buffer [ UARTTxBuf.write_pos ] = pData [ i ];
        UARTTxBuf.write_pos                         = (UARTTxBuf.write_pos + 1) % UART_TX_MAX_DEPTH;
    }

    return 0;
}

static void Protocol_UartHandle(const Protocol_Data_t *pData)
{
    if ( pData->CmdID == 0x20 )
    {
        //printf("0x20 is get\r\n");
        if(Prot_User.State < Prot_Start)
        {
            Prot_User.State = Prot_Start;
            // printf("Prot_Start \r\n");
        }
    }
    else if(pData->CmdID == 0x03 )
    {
        //printf("0x03 is get\r\n");
        if(Prot_User.State < Prot_Normal)
        {
            Prot_User.State = Prot_Normal;

            // printf("Prot_Normal \r\n");
        }

        if(Prot_User.State >= Prot_Start)
        {
            // if(pData->DataLen == 33)
            {
                if(BT_User.HF_Ctrl != pData->Data[0])
                {
                    BT_User.HF_Ctrl = pData->Data[0];
                }

                if(strncmp((const char *) ble_uerid, (const char *)&(pData->Data[1]), 32) != 0)
                {
                    memcpy(( uint8_t * )ble_uerid, (uint8_t *)&(pData->Data[1]), 32);
                }

                // esp_log_buffer_hex(TAG, ble_uerid, 32);
                // esp_log_buffer_hex(TAG, &(pData->Data[1]), 32);

                if(Ble_User.UseridUpdate == 0)
                {
                    bsp_Ble_Init();

                    SW_Send_Cnt_Set(150);

                    // printf("get uuid and init ble!!! \r\n");
                }

                Ble_User.UseridUpdate = 0xAA;
            }
        }
    }
    else if(pData->CmdID == 0x21 )
    {
        //printf("Wifi_OTA_Request is %d\r\n",Wifi_OTA_Request);
        if(pData->Data[0] == 1)
        {
            // if((pData->CmdID & 0xC0) == 0X40)
            // {
                if(Wifi_OTA_Request == 0)
                {
                    Wifi_OTA_Request = 1;
                    printf("get ota req! \r\n");
                }
            // }
        }
        if (pData->Data[1] == 1)
        {
            ODO_Clear_BLEinfo();
        }    
    }
    else
    {
    }
}

void UART_Put(Protocol_uint16_t Data)
{
   Protocol_uint32_t nextPos = 0u;

   nextPos = (UARTRxBuf.write_pos + 1) % UART_RX_MAX_DEPTH;

   if ( nextPos == UARTRxBuf.read_pos )
   {
       //队列已满，无法插入队列
   }
   else
   {
       UARTRxBuf.Rx_Buffer [ UARTRxBuf.write_pos ] = Data;
       UARTRxBuf.write_pos                         = (UARTRxBuf.write_pos + 1) % UART_RX_MAX_DEPTH;
   }
    //printf("into UARTRxBuf!!!!\r\n");
    return;
}



#define PROTOCOL_ID_12_DATA_LEN 18

/** 
 *   @brief    Protocol协议应用层数据赋值和发送
 */

void Protocol_User_Ctrl_Init(void )
{
    Prot_User.State = Prot_Idle;
    Prot_User.TimeDelay = 0;
}

void Uart_Send_Id10_Pro(void )
{
    uint8_t wtemp[1] = {0};
    wtemp[0] = 1;
    Protocol_Send(0x10, wtemp, 1);
}

void Uart_Send_Id12_Pro(void )
{
    uint8_t ID12[PROTOCOL_ID_12_DATA_LEN] = {0};
    ID12[0] |= (uint8_t)(BT_User.BT_Sts << 4);
    ID12[0] |=  Ble_User.Ble_Sts;
    unsigned int i = 0;
    for(i = 0;i < 14;i++)
    {
        ID12[ i + 1 ] = BT_Device_Name[ i ];
    }

    app_Ble_Time_Info_Struct *time = Get_Ble_TimeInfo();
    if(time == NULL)
    {
        ID12[15] = 0xff;
        ID12[16] = 0xff;
        ID12[17] = 0xff;
    }
    else
    {
        ID12[15] = time->u8Hour;
        ID12[16] = time->u8Minute;
        ID12[17] = time->u8Sec;
    }

    // if(ID12[15] != 0xff)
    // {
    //     printf("hour = %d, minute = %d, SEC = %d\n", ID12[15], ID12[16], ID12[17]);
    // }
    
    Protocol_Send(0x12, ID12, PROTOCOL_ID_12_DATA_LEN);
}

void Uart_Send_Id01_Pro(void)
{
    uint8_t ID01[6] = {0x00,0x00,0x00,0x00,0x00,0x00};
    if(Ble_User.Navi_Updat)
    {   
        ID01[0] = Ble_Navi_Data.Navi_Sts;
        ID01[1] = Ble_Navi_Data.Navi_Turn;
        ID01[2] = Ble_Navi_Data.Navi_Dte[0];
        ID01[3] = Ble_Navi_Data.Navi_Dte[1];
        ID01[4] = Ble_Navi_Data.Navi_Dte[2];
        ID01[5] = Ble_Navi_Data.Navi_Dte[3];

        //printf("转向编码：%d\r\n",Ble_Navi_Data.Navi_Turn);
    }
    Protocol_Send(0x01,ID01,6);
}


void Uart_Send_Id02_Pro(void)
{
    uint8_t ID02[1] = {0x00};
    ID02[0] =  BT_User.Call_Fitter_sts;
    Protocol_Send(0x02, ID02, 1);   
}


void Uart_Send_Id13(void)
{
    uint8_t wtemp[3] = {0};
    wtemp[0] = BL_INTERNAL_SW_YEAR;
    wtemp[1] = BL_INTERNAL_SW_MONTH;
    wtemp[2] = BL_INTERNAL_SW_DAY;
    Protocol_Send(0x13, wtemp, 3);   
}

uint16_t SW_Send_Cnt = 0;

void SW_Send_Cnt_Set(uint16_t val)
{
    SW_Send_Cnt = val;
}

void Prot_Send_Msg_Process(void )
{
    if(Prot_User.TimeDelay < 4)
    {
        Prot_User.TimeDelay ++;
    }
    else
    {
        Prot_User.TimeDelay = 0;
    }

    switch(Prot_User.TimeDelay)
    {
        case 0:
        {
            if(Prot_User.State < Prot_Start)
            {
                Uart_Send_Id10_Pro();

                // printf("send 0x10 \r\n");
            }
            break;
        }
        case 1:
        {
            if(Prot_User.State >=  Prot_Start)
            {
                Uart_Send_Id12_Pro();
                // Uart_Send_Id10_Pro();
            }
            break;
        }
        case 2:
        {
            if(Prot_User.State >=  Prot_Start)
            {
                Uart_Send_Id01_Pro();
            }
            break;
        }
        case 3:
        {
            if(Prot_User.State >=  Prot_Start)
            {
                Uart_Send_Id02_Pro();
            }
            break;
        }
        case 4:
        {
            if(Prot_User.State >=  Prot_Start)
            {
                SW_Send_Cnt ++;
                if(SW_Send_Cnt >= 200)
                {
                    Uart_Send_Id13();
                    SW_Send_Cnt = 0;
                }
            }
            break;
        }
        default:
        {
            break;
        }

    }

}
