#include <string.h>

#include "basedef.h"
#include "dbg.h"
#include "tlv_parser.h"
#include "cmd_registry.h"

#include "cmd_crypto.h"
#include "cmd_skpm.h"
#include "tal_operation.h"


//#define TA_VERSION "1.0.00.00"
//#define TA_VERSION_NAME "//SEC_TA_VERSION:" ## TA_VERSION ## "//"

AuthnrResult executeCmd(const BlobData* pBlobInput, BlobData* pBlobOutput)
{
    uint32 tag = 0;
    AuthnrResult authnrRet = AUTHNR_SUCCESS;
    BlobData blobInput = {0};
    BlobData blobOutput = {0};

//    printI("version:%s", TA_VERSION_NAME);

    do {
        //copy data form WSM to secure memory
        blobInput.dataSize = pBlobInput->length;
        blobInput.data = gTal.malloc(blobInput.dataSize);
        if (blobInput.data == NULL) {
            printE("blobInput.data malloc fail");
            authnrRet = AUTHNR_ERROR_MALLOC;
            break;
        }
        memcpy(blobInput.data, pBlobInput->data, pBlobInput->length);
        blobInput.length = blobInput.dataSize;

        blobOutput.dataSize = pBlobOutput->dataSize;
        blobOutput.data = gTal.malloc(blobOutput.dataSize);
        if (blobOutput.data == NULL) {
            printE("blobOutput.data malloc fail");
            authnrRet = AUTHNR_ERROR_MALLOC;
            break;
        }
        blobOutput.length = 0;

        printI("is:%d", blobInput.length);
        tag = getTag(pBlobInput, 0);
        switch (tag) {
            case TAG_TAD_SKPM_PROVISIONING_COMMAND:
                authnrRet = processSkpmProvisioning(&blobInput, &blobOutput);
                break;
            case TAG_TAD_DECRYPTION_COMMAND:
                authnrRet = processDecryption(&blobInput, &blobOutput);
                break;
            default:
                printE("not supported tag");
                authnrRet = AUTHNR_ERROR_NOT_SUPPORTED;
                break;
        }
    } while(0);

    if (pBlobOutput->data != NULL && blobOutput.data != NULL) {
        pBlobOutput->length = blobOutput.length;
        memcpy(pBlobOutput->data, blobOutput.data, pBlobOutput->length);
    } else {
        printE("output memory is null");
        pBlobOutput->length = 0;
        authnrRet = AUTHNR_ERROR_MALLOC;
    }
    printI("os:%d, ret: %d", pBlobOutput->length, authnrRet);

    if (blobInput.data != NULL) {
        gTal.free(blobInput.data, blobInput.dataSize);
        blobInput.data = NULL;
    }
    if (blobOutput.data != NULL) {
        gTal.free(blobOutput.data, blobOutput.dataSize);
        blobOutput.data = NULL;
    }

    return authnrRet;
}

