#include <sys/prctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "ap_extern.h"
#include "drv_uart_def.h"
#include "al_bluetooth.h"
#include "al_bluetooth_ctrl.h"
#include "al_bluetooth_upgrader.h"
#include "al_basictypes.h"
#include "al_console.h"
#include <gsl/gl_mutex.h>
#include <gsl/gl_task.h>
#ifdef CONFIG_BT_5851S
#include <gsl/gl_timer.h>
#endif
int uartbfd = 0;
CON_DEV Btcon_dev_t;

extern CON_UART con_uart;
extern pthread_mutex_t uartB_Lock;
extern pthread_cond_t uartB_Strat;
extern al_uint8 bStandby;

pthread_mutex_t uartB_Action = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t uartB_Active = PTHREAD_COND_INITIALIZER;;
pthread_t BtConsoleThread;
pthread_mutex_t reqMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t txMutex = PTHREAD_MUTEX_INITIALIZER;

static BT_SendBuffer_t _stBTSendBuf;
static BT_Event_LinkList_Node_t *_pstSendBtEvtListTail;
static BT_ModCbk_pf g_pfBTCallback = NULL;
static GL_Task_t BT_DAEMON = NULL;
static GL_Task_t BT_LISTENER = NULL;
#ifdef CONFIG_BT_5851S
GL_Timer_t gBTQuery_timerid = 0;
#endif
pCON_DEV get_pBtCON_DEV(void)
{
    return &Btcon_dev_t;
}

void bluetooth_cmd_send(al_uint8 * str, al_uint size)
{
    int count = 0, outsize = 0;
    al_uint len = 0;
	al_uint8 buff[UART_BUF_SIZE] = { 0 };

    outsize = size;	
    while (1)
    {
        len = (outsize >= UART_BUF_SIZE) ? UART_BUF_SIZE : outsize;
        memcpy(buff, (str + count * UART_BUF_SIZE), len);
        write(uartbfd, buff, len);
        if (outsize > UART_BUF_SIZE)
        {
            count++;
            outsize -= UART_BUF_SIZE;
        }
        else
        {
            break;
        }
    }
}

void Al_Bluetooth_Enable(void)
{
    pCON_DEV pcon = &Btcon_dev_t;

    pcon->bActive = TRUE;
    CONSOLE_UART_START(UartB);
	#ifdef CONFIG_BT_5851S
	bStandby = FALSE;
	#endif
    pthread_cond_signal(&uartB_Active);
	pthread_mutex_init(&txMutex,NULL);	

    //pthread_cond_broadcast(&uartB_Strat);
}

void Al_Bluetooth_Disable(void)
{
    pCON_DEV pcon = &Btcon_dev_t;

    if (!pcon->bActive)
        return;

    if (!bStandby)
    {
        Al_Bluetooth_Set_Action(BT_CMD_STANDBY, NULL, 0);
    }
    pcon->bActive = FALSE;
    con_uart.uartB_Stop = TRUE;

    GL_TaskSleep(50);
}

void Al_Bluetooth_Destory(void)
{
    //Al_Bluetooth_Disable();
    con_uart.uartB_Thread = FALSE;
    //Al_Bluetooth_Enable();

    /*if(BT_DAEMON)
     * GL_TaskDestroyOne(BT_DAEMON);
     * if(BT_LISTENER)
     * GL_TaskDestroyOne(BT_LISTENER); */
    pthread_mutex_destroy(&uartB_Lock);
    pthread_mutex_destroy(&uartB_Action);
	pthread_mutex_destroy(&reqMutex);
    pthread_cond_destroy(&uartB_Strat);
    pthread_cond_destroy(&uartB_Active);
	pthread_mutex_destroy(&txMutex);	
}


// send command to ap
BT_Status_e _bt_SendEvt(BT_MessageBody_t stEvt)
{
	BT_Event_LinkList_Node_t *pstNew;
	
	pstNew = (BT_Event_LinkList_Node_t *) malloc(sizeof(BT_Event_LinkList_Node_t));
	if (pstNew == NULL)
	{
		return BT_ERR_FAILURE;
	}
	pstNew->stEvt = stEvt;
#if defined(CONFIG_BT_RDA5856)||defined(CONFIG_BT_POL6556)
	if(stEvt.dCmdSize != 0)
	{
		pstNew->stEvt.pdata = (al_uint8 *)malloc(sizeof(al_uint8)*(stEvt.dCmdSize));
		if (pstNew->stEvt.pdata == NULL)
		{
			free(pstNew);
			pstNew = NULL;
			return BT_ERR_FAILURE;
		}
		memset(pstNew->stEvt.pdata,0x0,stEvt.dCmdSize);
		memcpy(pstNew->stEvt.pdata,stEvt.pdata,stEvt.dCmdSize);
	}
#endif
	if (_stBTSendBuf.pstEvtList == NULL)
	{
		_stBTSendBuf.pstEvtList = pstNew;
		_pstSendBtEvtListTail = pstNew;
		_pstSendBtEvtListTail->pstNext = NULL;
	}
	else
	{
		if (_pstSendBtEvtListTail)
		{
			_pstSendBtEvtListTail->pstNext = pstNew;
			_pstSendBtEvtListTail = pstNew;
			_pstSendBtEvtListTail->pstNext = NULL;
		}
		else
		{
#if defined(CONFIG_BT_RDA5856)||defined(CONFIG_BT_POL6556)
			if(pstNew->stEvt.pdata)
				free(pstNew->stEvt.pdata);
#endif
			free(pstNew);
			pstNew = NULL;
			return BT_ERR_FAILURE;
		}
	}

	return BT_SUCCESS;
}

static void _bt_SendModule(void)
{
    //send Event to App
    if (_stBTSendBuf.pstEvtList)
    {
        BT_Event_LinkList_Node_t *pEHead = NULL, *pEDel = NULL;
        //printf("%s send event to App\n", __FUNCTION__);
        pEHead = _stBTSendBuf.pstEvtList;
        _stBTSendBuf.pstEvtList = NULL;
        while (pEHead)
        {
            if (g_pfBTCallback != NULL)
            {
#if defined(CONFIG_BT_RDA5856)||defined(CONFIG_BT_POL6556)
                g_pfBTCallback(pEHead->stEvt);
#else
				g_pfBTCallback(pEHead->stEvt.dMessage, pEHead->stEvt.dParam);
#endif
            }
			pEDel = pEHead;
			pEHead = pEHead->pstNext;
#if defined(CONFIG_BT_RDA5856)||defined(CONFIG_BT_POL6556)
			if(pEDel->stEvt.pdata)
				free(pEDel->stEvt.pdata);
#endif
			free(pEDel);
			pEDel = NULL;
        }
    }
    else
    {
        /*
         * if(gBTTaskStatus!=BT_TASK_IDLE)
         * {
         * gBTTaskStatus = BT_TASK_IDLE;
         * BT_TASK_IDLE_CNT=0;
         * }
         * else
         * {
         * BT_TASK_IDLE_CNT++;
         * } */
    }
}


void Al_BtMainRoutine(void *pParam)
{
    //static BOOL BTEnableStatus = 1;
    pCON_DEV pcon = &Btcon_dev_t;

    prctl(PR_SET_NAME , __FUNCTION__, NULL, NULL, NULL);
    _stBTSendBuf.pstEvtList = NULL;
    _stBTSendBuf.pstFrmList = NULL;

    while (con_uart.uartB_Thread)
    {
        pthread_mutex_lock(&uartB_Action);
        if (pcon->bActive)
        {
            _bt_SendModule();
            _stBTSendBuf.pstFrmList = NULL;

        }
        else
        {
            _stBTSendBuf.pstEvtList = NULL;
            _stBTSendBuf.pstFrmList = NULL;

            pthread_cond_wait(&uartB_Active, &uartB_Action);
        }
        GL_TaskSleep(BT_DAEMON_DELAY);
        pthread_mutex_unlock(&uartB_Action);
    }
    GL_TaskSelfDelete();

}

static void blueTooth_hanlder(void *arg)
{
    pCON_DEV pconB = &Btcon_dev_t;
    prctl(PR_SET_NAME , __FUNCTION__, NULL, NULL, NULL);

    do
    {
        pthread_mutex_lock(&uartB_Lock);
        con_uart.uartB_Stop = FALSE;

        pconB->pid = 0;

        if (con_uart.uartB_Thread)
        {
            //con_uart.UART_UARTB_Wait_Status = TRUE;
            pthread_cond_wait(&uartB_Strat, &uartB_Lock);
            //con_uart.UART_UARTB_Wait_Status = FALSE;
        }
		
		Al_Bluetooth_Listener(pconB);

        pthread_mutex_unlock(&uartB_Lock);
    }
    while (con_uart.uartB_Thread);

    GL_TaskSelfDelete();
    return;
}

#ifdef CONFIG_BT_5851S
void BlueToothQueryTimer()
{
	prctl(PR_SET_NAME , __FUNCTION__, NULL, NULL, NULL);
	Al_Bluetooth_Set_Action(BT_CMD_QUERY_STATUS, NULL, 0);
}
#endif

void BlueTooth_Init(BT_ModualCfg_t * pBT_ModualCfg)
{
    pCON_DEV pcon = &Btcon_dev_t;

    //con_uart.uartB_Thread_close = FALSE;
    con_uart.uartB_Thread = TRUE;
    pcon->bActive = FALSE;

    if ((pBT_ModualCfg != NULL) && (pBT_ModualCfg->pfCallBack != NULL))
    {
        g_pfBTCallback = pBT_ModualCfg->pfCallBack;
    }

    if (GL_TaskCreate("Bluetooth Daemon", (void *) Al_BtMainRoutine, NULL, 3, 4096, TRUE, &(BT_DAEMON)) != GL_SUCCESS)
        printf("pthread_create fail: Al_BtMainRoutine thread\n");


    if (GL_TaskCreate("Bluetooth Listener", (void *) blueTooth_hanlder, NULL, 3, 4096, TRUE, &(BT_LISTENER)) !=
        GL_SUCCESS)
        printf("pthread_create fail: blueTooth_hanlder thread\n");

#ifdef CONFIG_BT_5851S		
		GL_TimerCreate("BTStatusQuery", BlueToothQueryTimer, NULL, TRUE, 500 , TRUE, &gBTQuery_timerid);
#endif

    //con_uart.uartB_Thread_close = TRUE;
}
