/**
 *  @file ins_ut_config.c
 *  @details config unit test
 *
 */

#include <stdlib.h>
#include <string.h>
#include "unittest.h"
#include "unittest/dcf/ins_ut_dcf.h"
#include "ins_mw_dcf.h"
#include "ins_pal_error_code.h"
#include "ins_pal_fs.h"
#define INSLOG_TAG "UtDcf"
#include "ins_comm_log.h"

static int32_t InsUT_Dcf_Init(int32_t argc, char **argv)
{
    uint32_t ret = 0;
    uint8_t driver = 0;
    const char rootDriver = 'C';
    uint32_t lastValidDirNo = 0;

    (void)argc;
    (void)argv;

    ret = InsMw_Dcf_ConfigDrive(driver, &rootDriver, "DCIM");
    if(ret != INSERR_OK)
    {
        INSLOG_E("InsMw_Dcf_ConfigDrive failed");
        return ret;
    }

    ret = InsMw_Dcf_Init(driver);
    if(ret != INSERR_OK)
    {
        INSLOG_E("InsMw_Dcf_Init failed");
        return ret;
    }

    ret = InsMw_Dcf_ScanRootStep1(driver, &lastValidDirNo);
    if(ret != INSERR_OK)
    {
        INSLOG_E("InsMw_Dcf_ScanRootStep1 failed");
        return ret;
    }

    ret = InsMw_Dcf_ScanRootStep2(driver, lastValidDirNo);
    if(ret != INSERR_OK)
    {
        INSLOG_E("InsMw_Dcf_ScanRootStep2 failed");
        return ret;
    }

    return ret;
}

static INSMW_DCF_FILE_TYPE_e InsUT_Dcf_GetTypeByPara(char *argv)
{
    INSMW_DCF_FILE_TYPE_e fileType = INSMW_DCF_FILE_TYPE_JPG;

    if(strcmp(argv, "jpg") == 0)
    {
        fileType = INSMW_DCF_FILE_TYPE_JPG;
    }
    else if(strcmp(argv, "raw") == 0)
    {
        fileType = INSMW_DCF_FILE_TYPE_RAW;
    }
    else if(strcmp(argv, "dng") == 0)
    {
        fileType = INSMW_DCF_FILE_TYPE_DNG;
    }
    else if(strcmp(argv, "insp") == 0)
    {
        fileType = INSMW_DCF_FILE_TYPE_INSP;
    }
    else if(strcmp(argv, "mp4") == 0)
    {
        fileType = INSMW_DCF_FILE_TYPE_MP4;
    }
    else if(strcmp(argv, "insv") == 0)
    {
        fileType = INSMW_DCF_FILE_TYPE_INSV;
    }
    else if(strcmp(argv, "aac") == 0)
    {
        fileType = INSMW_DCF_FILE_TYPE_AUDIO;
    }
    else
    {
        INSLOG_W("Not supported type: %s!", argv);
    }
    return fileType;
}

static int32_t InsUT_Dcf_CreateName(int32_t argc, char **argv)
{
    uint32_t ret = 0;
    char fileName[64] = {0};
    uint32_t vin_id = 0;
    uint32_t stream_id = 0;
    InsPal_FS_File_t * pFile;

    INSMW_DCF_FILE_TYPE_e fileType;

    if(argc < 3)
    {
        INSLOG_W("Input para not enough!");
        return INSERR_NG;
    }

    fileType = InsUT_Dcf_GetTypeByPara(argv[0]);

    vin_id = atoi(argv[1]);
    stream_id = atoi(argv[2]);

    ret = InsMw_Dcf_CreateFileName(0, 0, fileType, fileName, vin_id, stream_id);
    if(ret != INSERR_OK)
    {
        INSLOG_E("InsMw_Dcf_CreateFileName failed");
        return ret;
    }
    INSLOG_I("Create File Name %s", fileName);

    InsPal_FS_Open(fileName, "wb+", &pFile);
    InsPal_FS_Sync(pFile);
    InsPal_FS_Close(pFile);

    ret = InsMw_Dcf_UpdateFile(fileName);
    if(ret != INSERR_OK)
    {
        INSLOG_E("InsMw_Dcf_UpdateFile failed");
        return ret;
    }
    return ret;
}

static int32_t InsUT_Dcf_Delete(int32_t argc, char **argv)
{
    uint32_t ret = 0;

    if(argc < 1)
    {
        INSLOG_W("Input para not enough!");
        return INSERR_NG;
    }

    INSLOG_I("Delete File Name %s", argv[0]);
    ret = InsMw_Dcf_DeleteFile(argv[0]);
    if(ret != INSERR_OK)
    {
        INSLOG_E("InsMw_Dcf_DeleteFile failed");
        return ret;
    }
    return ret;
}

static int32_t InsUT_Dcf_Destroy(int32_t argc, char **argv)
{
    uint32_t ret = 0;
    uint8_t driver = 0;

    (void)argc;
    (void)argv;

    INSLOG_I("Dcf destroy");
    ret = InsMw_Dcf_Destroy(driver);
    if(ret != INSERR_OK)
    {
        INSLOG_E("InsMw_Dcf_Destroy failed");
        return ret;
    }
    return ret;
}

static int32_t InsUT_Dcf_CreateGroup(int32_t argc, char **argv)
{
    uint32_t ret = 0;
    char fileName[2][64] = {{0},{0}};
    uint32_t vin_id[2] = {0};
    uint32_t stream_id[2] = {0};
    InsPal_FS_File_t * pFile;

    INSMW_DCF_FILE_TYPE_e fileType[2];

    if(argc < 6)
    {
        INSLOG_W("Input para not enough!");
        return INSERR_NG;
    }

    fileType[0] = InsUT_Dcf_GetTypeByPara(argv[0]);
    fileType[1] = InsUT_Dcf_GetTypeByPara(argv[3]);

    vin_id[0] = atoi(argv[1]);
    stream_id[0] = atoi(argv[2]);
    vin_id[1] = atoi(argv[4]);
    stream_id[1] = atoi(argv[5]);

    ret = InsMw_Dcf_CreateFileName(0, 0, fileType[0], fileName[0], vin_id[0], stream_id[0]);
    if(ret != INSERR_OK)
    {
        INSLOG_E("InsMw_Dcf_CreateFileName failed");
        return ret;
    }
    INSLOG_I("Create File Name %s", fileName);

    ret = InsMw_Dcf_CreateFileName(0, 0, fileType[1], fileName[1], vin_id[1], stream_id[1]);
    if(ret != INSERR_OK)
    {
        INSLOG_E("InsMw_Dcf_CreateFileName failed");
        return ret;
    }

    InsPal_FS_Open(fileName[0], "wb+", &pFile);
    InsPal_FS_Sync(pFile);
    InsPal_FS_Close(pFile);

    InsPal_FS_Open(fileName[1], "wb+", &pFile);
    InsPal_FS_Sync(pFile);
    InsPal_FS_Close(pFile);

    ret = InsMw_Dcf_UpdateFile(fileName[0]);
    if(ret != INSERR_OK)
    {
        INSLOG_E("InsMw_Dcf_UpdateFile failed");
        return ret;
    }
    ret = InsMw_Dcf_UpdateFile(fileName[1]);
    if(ret != INSERR_OK)
    {
        INSLOG_E("InsMw_Dcf_UpdateFile failed");
        return ret;
    }
    return ret;
}

static int32_t InsUT_Dcf_GetTypeCnt(int32_t argc, char **argv)
{
    (void)argc;
    (void)argv;
    return 0;
}

InsUT_Unittest_CmdInfo_t g_ut_cmd_dcf[INSUT_CMDCNT_DCF] =
{
    {InsUT_Dcf_Init,        0, NULL, "init",            "No Param: Init dcf"},
    {InsUT_Dcf_CreateName,  0, NULL, "create",          "[type][vin_id][stream_id]: Create a file name"},
    {InsUT_Dcf_CreateGroup, 0, NULL, "create_group",    "[type0][vin_id0][stream_id0][type1][vin_id1][stream_id1]: Create a group names"},
    {InsUT_Dcf_Delete,      0, NULL, "delete",          "[file_name]: Delete a file"},
    {InsUT_Dcf_GetTypeCnt,  0, NULL, "get_type_cnt",    "[type]: Get nums of a type"},
    {InsUT_Dcf_Destroy,     0, NULL, "destroy",         "No Param: Destroy dcf"},
};
