/**
 *  @file ins_ut_media.c
 *  @details media unit test
 *
 */
#define INSLOG_TAG     "MEDIAMGR_UT"

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

#include "AmbaTypes.h"
#include "SvcLog.h"

/* ins head files */
#include "unittest.h"
#include "ins_ut_media.h"
#include "ins_ut_media_service.h"
#include "ins_mw_mediamgr.h"
#include "ins_pal_error_code.h"
#include "ins_pal_task.h"

extern InsMw_MediaMgr_Context_t* InsMw_MediaMgr_GetContextForUtest(void);

static InsMw_MediaMgr_Context_t* g_pmediamgr_ut=NULL;

static int32_t InsUT_MediaMgr_Init(int32_t argc, char **argv);
static int32_t InsUT_MediaMgr_DeInit(int32_t argc, char **argv);
static int32_t InsUT_MediaMgr_Selftest(int32_t argc, char **argv);
static int32_t InsUT_MediaMgr_LiveviewStart(int32_t argc, char **argv);
static int32_t InsUT_MediaMgr_LiveViewStop(int32_t argc, char **argv);
static int32_t InsUT_MediaMgr_RecordStart(int32_t argc, char **argv);
static int32_t InsUT_MediaMgr_RecordStop(int32_t argc, char **argv);


/**
 * Check whether the mediamgr is initialized  
 * 0:OK, other:NG
 */
uint32_t InsUT_MediaMgr_InitCheck(void)
{
    return (NULL==g_pmediamgr_ut)? ERRMED_INVAL : INSERR_OK;
}


/**
 * unittest for media manager init
 * return 0:OK, other:FAIL
 */
static int32_t InsUT_MediaMgr_Init(int32_t argc, char **argv)
{
    uint32_t ret_val = INSERR_OK;

    (void)argc;
    (void)argv;      
    if(NULL!=g_pmediamgr_ut)
    {
        SvcLog_DBG(INSLOG_TAG, "mediamgr already initialized.", 0U, 0U);
        return INSERR_OK;
    }

    ret_val = InsMw_MediaMgr_Init(&g_pmediamgr_ut);
    if( (ERRMED_INIT == ret_val)
        && (NULL==g_pmediamgr_ut))
    {
        g_pmediamgr_ut = InsMw_MediaMgr_GetContextForUtest();
    }
    
    if(g_pmediamgr_ut != NULL)
    {
        ret_val = g_pmediamgr_ut->media_init();

        /* init media service unittest */
        ret_val |= InsUT_MediaSvc_Init();
    }  

    SvcLog_DBG(INSLOG_TAG, "InsUT_MediaMgr_Init() finish.", 0U, 0U);
    return ret_val;
}

/**
 * unittest for media manager de init
 * return 0:OK, other:FAIL
 */
static int32_t InsUT_MediaMgr_DeInit(int32_t argc, char **argv)
{
    uint32_t ret_val = INSERR_OK;

    (void)argc;
    (void)argv;    
    if(NULL==g_pmediamgr_ut)
    {
        SvcLog_NG(INSLOG_TAG, "mediamgr not initialized.", 0U, 0U);
        return ERRMED_INVAL;
    }

    InsUT_MediaSvc_DeInit();

    ret_val = InsMw_MediaMgr_DeInit(&g_pmediamgr_ut);
    g_pmediamgr_ut = NULL;    

    SvcLog_DBG(INSLOG_TAG, "InsUT_MediaMgr_DeInit() finish.", 0U, 0U);
    return ret_val;
}


/**
* unittest for start Liveview with display on VOUT
* @return ErrorCode
*/
static int32_t InsUT_MediaMgr_LiveviewStart(int32_t argc, char **argv)
{
    uint32_t ret_value = INSERR_OK;
    
    (void)argc;
    (void)argv;      
    if(NULL==g_pmediamgr_ut)
    {
        SvcLog_NG(INSLOG_TAG, "mediamgr not initialized.", 0U, 0U);
        return ERRMED_INVAL;
    }

    ret_value = g_pmediamgr_ut->liveview_start();

    SvcLog_DBG(INSLOG_TAG, "InsUT_MediaMgr_LiveviewStart() finish.", 0U, 0U);
    return ret_value;
}


/**
* unittest for media manager selftest
* @return ErrorCode
*/
static int32_t InsUT_MediaMgr_Selftest(int32_t argc, char **argv)
{
    uint32_t ret_value = INSERR_OK;
    int32_t idx=0;
    int32_t  test_num =1, time_val=3000, pre_time = 1000;

    
    switch(argc)
    {
        case 2: 
        {            
            test_num = atoi(argv[0]);
            time_val = atoi(argv[1]);
        }
        break;
        case 1:
        {
            test_num = atoi(argv[0]);
        }
        break;
        default:
            SvcLog_NG(INSLOG_TAG, "unsupport paras, will using default value, argc:%d", argc, 0U);
    }
    test_num = (test_num<1)? 1 : test_num;
    time_val = (time_val<1000)? 1000 : time_val;

    SvcLog_DBG(INSLOG_TAG, "mediamgr selftest test_num:%d, time_val:%d", test_num, time_val);

    ret_value = InsUT_MediaMgr_Init(0, NULL);
    for(idx=0; idx<test_num; idx++)
    {
        if(INSERR_OK!=ret_value)
        {
            SvcLog_NG(INSLOG_TAG, "mediamgr selftest count:%d fail.", (idx+1), 0U);
            break;
        }

        if(INSERR_OK==ret_value)
        {
            InsPal_Task_Sleep(pre_time);
            ret_value |= InsUT_MediaMgr_LiveviewStart(0, NULL);
        }
        
        if(INSERR_OK==ret_value)
        {
            InsPal_Task_Sleep(pre_time);
            ret_value |= InsUT_MediaMgr_RecordStart(0, NULL);
        }

        if(INSERR_OK==ret_value)
        {
            InsPal_Task_Sleep(time_val);
            ret_value |= InsUT_MediaMgr_RecordStop(0, NULL);
        }

        if(INSERR_OK==ret_value)
        {
            InsPal_Task_Sleep(pre_time);
            ret_value |= InsUT_MediaMgr_LiveViewStop(0, NULL);
        }

        SvcLog_OK(INSLOG_TAG, "mediamgr selftest count:%d success.", (idx+1), 0U);
    }
    ret_value |= InsUT_MediaMgr_DeInit(0, NULL);

    return ret_value;
}



/**
* unittest for stop Liveview with display on VOUT
* @return ErrorCode
*/
static int32_t InsUT_MediaMgr_LiveViewStop(int32_t argc, char **argv)
{
    uint32_t ret_value = INSERR_OK;

    (void)argc;
    (void)argv;      
    if(NULL==g_pmediamgr_ut)
    {
        SvcLog_NG(INSLOG_TAG, "mediamgr not initialized.", 0U, 0U);
        return ERRMED_INVAL;
    }

    ret_value = g_pmediamgr_ut->liveview_stop();

    SvcLog_DBG(INSLOG_TAG, "InsUT_MediaMgr_LiveViewStop() finish.", 0U, 0U);
    return ret_value;
}


/**
* unittest for start record
* @return ErrorCode
*/
static int32_t InsUT_MediaMgr_RecordStart(int32_t argc, char **argv)
{
    uint32_t ret_value = INSERR_OK;

    (void)argc;
    (void)argv;      
    if(NULL==g_pmediamgr_ut)
    {
        SvcLog_NG(INSLOG_TAG, "mediamgr not initialized.", 0U, 0U);
        return ERRMED_INVAL;
    }

    if(argc>0)
    {
        uint32_t strm_bits = 0;
        strm_bits = atoi(argv[0]);
        InsMw_MediaMgr_SetRecordStreamBits(g_pmediamgr_ut, strm_bits);
    }

    ret_value = g_pmediamgr_ut->record_start();

    SvcLog_DBG(INSLOG_TAG, "InsUT_MediaMgr_RecordStart() finish.", 0U, 0U);
    return ret_value;
}

/**
* unittest for stop record
* @return ErrorCode
*/
static int32_t InsUT_MediaMgr_RecordStop(int32_t argc, char **argv)
{
    uint32_t ret_value = INSERR_OK;

    (void)argc;
    (void)argv;      
    if(NULL==g_pmediamgr_ut)
    {
        SvcLog_NG(INSLOG_TAG, "mediamgr not initialized.", 0U, 0U);
        return ERRMED_INVAL;
    }

    ret_value = g_pmediamgr_ut->record_stop();

    SvcLog_DBG(INSLOG_TAG, "InsUT_MediaMgr_RecordStop() finish.", 0U, 0U);
    return ret_value;
}


InsUT_Unittest_CmdInfo_t g_ut_cmd_media_manager[INSUT_CMDCNT_MEDIA_MANAGER] = 
{
    {InsUT_MediaMgr_Init,           0, NULL, "init",                "No Param(result:OK)"},
    {InsUT_MediaMgr_DeInit,         0, NULL, "deinit",              "No Param(result:OK)"},
    {InsUT_MediaMgr_Selftest,       0, NULL, "selftest",            "<num> <time_interval>(result:OK)"},
    {InsUT_MediaMgr_LiveviewStart,  0, NULL, "live_start",          "No Param(result:OK)"},
    {InsUT_MediaMgr_LiveViewStop,   0, NULL, "live_stop",           "No Param(result:OK)"},
    {InsUT_MediaMgr_RecordStart,    0, NULL, "rec_start",           "(strmid)[1|2|..](result:OK)"},
    {InsUT_MediaMgr_RecordStop,     0, NULL, "rec_stop",            "No Param(result:OK)"},
};


InsUT_Unittest_CmdInfo_t g_ut_cmd_media[INSUT_CMDCNT_MEDIA] = 
{
    {NULL,	INSUT_CMDCNT_MEDIA_MANAGER,			g_ut_cmd_media_manager,	        "manager",      "Media Manager"},
    {NULL,	INSUT_CMDCNT_MEDIA_SERVICE,	        g_ut_cmd_media_service,		    "service",      "Media Service"},
};

