//
// Created by jk on 17-7-11.
//
#include <stdint.h>
#include "ifaa_ta_commandId.h"
#include "ifaa_ta_common.h"

#include "ta_logger.h"
#include "ta_banner_print.h"

#include "tzWrappers/TzwMemory.h"

extern const char *IFAA_VERSION_NUMBER;
const char *IFAA_TA_NAME="IFBIO";

static uint8_t gQseeLogMask = 0;

void tz_app_cmd_handler(void* cmd, uint32_t cmdlen,void* rsp, uint32_t rsplen);
void tz_app_shutdown(void);
void tz_app_init(void);


void tz_app_cmd_handler(void* cmd, uint32_t cmdlen,
                        void* rsp, uint32_t rsplen)
{
    if (rsp == NULL || rsplen < sizeof(qsc_send_cmd_rsp_t)) {
        LOG_E("rsp is null or rsplen is invalid");
        return;
    }

    uint8_t *out = rsp;
    qsc_send_cmd_rsp_t *pRsp = (qsc_send_cmd_rsp_t*)(rsp);
    uint32_t in_len = cmdlen;
    uint32_t *out_len = &rsplen;

    do{
        uint8_t *in = (uint8_t *) tzwMalloc(cmdlen);
        if (in != NULL) {
            memcpy(in, cmd, cmdlen);
        } else {
            LOG_E("tzwMalloc failed");
            goto exit;
        }

        IFAA_Result status = IFAA_TaInvokeCmd(in, in_len, out, out_len);
exit:

#if defined(TRANSMIT_LOG_TO_CA)
#ifdef TA_RELEASE
        if (IFAA_ERR_SUCCESS != status)
#endif /*TA_RELEASE*/
        {
            int len = 0;
            qsc_send_cmd_rsp_t *logOut = (qsc_send_cmd_rsp_t*)(rsp);
            char *ptr = (char*)logOut->log_buf;
            logOut->log_len= 0;
            while(!isStackLogEmpty()) {
                if( LOGGER_BUF_LEN < logOut->log_len){
                    LOG_Raw("LOGGER_BUF_LEN is too samll to contain all TA log");
                    break;
                }

                char *str = popStackLog(&len);
                *((uint32_t*)ptr) = len;
                ptr += 4;

                strncpy(ptr, str, len);
                ptr += len;

                logOut->log_len += (len + 4);

                tzwFree(str);
            }
        }
#endif /*TRANSMIT_LOG_TO_CA*/

        // return status as the result of this command
        pRsp->status = status;
		
        tzwFree(in);

    }while(0);
}

void tz_app_shutdown(void)
{
    //add log for shutdown();
	qsee_log_set_mask(gQseeLogMask);
	LOG_I("ifbio is shutdown.");
}

void tz_app_init(void)
{
    //add log for init();
    gQseeLogMask = qsee_log_get_mask();
    qsee_log_set_mask(LOG_MASK);

	print_banner(IFAA_TA_NAME, IFAA_VERSION_NUMBER);
}
