/* =========================================================================
   example.c -- Example code for QCBOR

   Copyright (c) 2020-2021, Laurence Lundblade. All rights reserved.
   Copyright (c) 2021, Arm Limited. All rights reserved.

   SPDX-License-Identifier: BSD-3-Clause

   See BSD-3-Clause license in file named "LICENSE"

   Created on 6/30/2020
  ========================================================================== */

#include <stdio.h>
#include "example.h"
#include "qcbor/qcbor_encode.h"
#include "qcbor/qcbor_decode.h"
#include "qcbor/qcbor_spiffy_decode.h"
#include "qcbor/qcbor_number_decode.h"


/**
 * This is a simple example of encoding and decoding some CBOR from
 * and to a C structure.
 *
 * This also includes a comparison between the original structure
 * and the one decoded from the CBOR to confirm correctness.
 */


#define MAX_CYLINDERS 16

/**
 * The data structure representing a car engine that is encoded and
 * decoded in this example.
 */
typedef struct
{
   UsefulBufC Manufacturer;
   int64_t    uDisplacement;
   int64_t    uHorsePower;
#ifndef USEFULBUF_DISABLE_ALL_FLOAT
   double     dDesignedCompresion;
#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
   int64_t    uNumCylinders;
   bool       bTurboCharged;
#ifndef USEFULBUF_DISABLE_ALL_FLOAT
   struct {
      double dMeasuredCompression;
   } cylinders[MAX_CYLINDERS];
#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
} CarEngine;


/**
 * @brief Initialize the Engine data structure with values to encode.
 *
 * @param[out] pE   The Engine structure to fill in
 */
void EngineInit(CarEngine *pE)
{
   pE->Manufacturer        = UsefulBuf_FROM_SZ_LITERAL("Porsche");
   pE->uDisplacement       = 3296;
   pE->uHorsePower         = 210;
#ifndef USEFULBUF_DISABLE_ALL_FLOAT
   pE->dDesignedCompresion = 9.1;
#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
   pE->uNumCylinders       = 6;
   pE->bTurboCharged       = false;

#ifndef USEFULBUF_DISABLE_ALL_FLOAT
   pE->cylinders[0].dMeasuredCompression = 9.0;
   pE->cylinders[1].dMeasuredCompression = 9.2;
   pE->cylinders[2].dMeasuredCompression = 8.9;
   pE->cylinders[3].dMeasuredCompression = 8.9;
   pE->cylinders[4].dMeasuredCompression = 9.1;
   pE->cylinders[5].dMeasuredCompression = 9.0;
#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
}


/**
 * @brief Compare two Engine structure for equality.
 *
 * @param[in] pE1  First Engine to compare.
 * @param[in] pE2  Second Engine to compare.
 *
 * @retval Return @c true if the two Engine data structures are exactly the
 *         same.
 */
static bool EngineCompare(const CarEngine *pE1, const CarEngine *pE2)
{
   if(pE1->uNumCylinders != pE2->uNumCylinders) {
      return false;
   }
   if(pE1->bTurboCharged != pE2->bTurboCharged) {
      return false;
   }
   if(pE1->uDisplacement != pE2->uDisplacement) {
      return false;
   }
   if(pE1->uHorsePower != pE2->uHorsePower) {
      return false;
   }
#ifndef USEFULBUF_DISABLE_ALL_FLOAT
   if(pE1->dDesignedCompresion != pE2->dDesignedCompresion) {
      return false;
   }
   for(int64_t i = 0; i < pE2->uNumCylinders; i++) {
      if(pE1->cylinders[i].dMeasuredCompression !=
         pE2->cylinders[i].dMeasuredCompression) {
         return false;
      }
   }
#endif /* USEFULBUF_DISABLE_ALL_FLOAT */

   if(UsefulBuf_Compare(pE1->Manufacturer, pE2->Manufacturer)) {
      return false;
   }

    return true;
}


/**
 * @brief Encode an initialized CarEngine data structure in CBOR.
 *
 * @param[in] pEngine  The data structure to encode.
 * @param[in] Buffer   Pointer and length of buffer to output to.
 *
 * @return  The pointer and length of the encoded CBOR or
 *          @ref NULLUsefulBufC on error.
 *
 * This encodes the input structure @c pEngine as a CBOR map of
 * label-value pairs. An array of float is one of the items in the
 * map.
 *
 * This uses the UsefulBuf convention of passing in a non-const empty
 * buffer to be filled in and returning a filled in const buffer. The
 * buffer to write into is given as a pointer and length in a
 * UsefulBuf. The buffer returned with the encoded CBOR is a
 * UsefulBufC also a pointer and length. In this implementation the
 * pointer to the returned data is exactly the same as that of the
 * empty buffer. The returned length will be smaller than or equal to
 * that of the empty buffer. This gives correct const-ness for the
 * buffer passed in and the data returned.
 *
 * @c Buffer must be big enough to hold the output. If it is not @ref
 * NULLUsefulBufC will be returned. @ref NULLUsefulBufC will be
 * returned for any other encoding errors.
 *
 * This can be called with @c Buffer set to @ref SizeCalculateUsefulBuf
 * in which case the size of the encoded engine will be calculated,
 * but no actual encoded CBOR will be output. The calculated size is
 * in @c .len of the returned @ref UsefulBufC.
 */
UsefulBufC EncodeEngine(const CarEngine *pEngine, UsefulBuf Buffer)
{
   /* Set up the encoding context with the output buffer */
    QCBOREncodeContext EncodeCtx;
    QCBOREncode_Init(&EncodeCtx, Buffer);

    /* Proceed to output all the items, letting the internal error
     * tracking do its work */
    QCBOREncode_OpenMap(&EncodeCtx);
    QCBOREncode_AddTextToMapSZ(&EncodeCtx, "Manufacturer", pEngine->Manufacturer);
    QCBOREncode_AddInt64ToMapSZ(&EncodeCtx, "NumCylinders", pEngine->uNumCylinders);
    QCBOREncode_AddInt64ToMapSZ(&EncodeCtx, "Displacement", pEngine->uDisplacement);
    QCBOREncode_AddInt64ToMapSZ(&EncodeCtx, "Horsepower", pEngine->uHorsePower);
#ifndef USEFULBUF_DISABLE_ALL_FLOAT
    QCBOREncode_AddDoubleToMapSZ(&EncodeCtx, "DesignedCompression", pEngine->dDesignedCompresion);
#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
   QCBOREncode_OpenArrayInMapSZ(&EncodeCtx, "Cylinders");
#ifndef USEFULBUF_DISABLE_ALL_FLOAT
    for(int64_t i = 0 ; i < pEngine->uNumCylinders; i++) {
        QCBOREncode_AddDouble(&EncodeCtx,
                              pEngine->cylinders[i].dMeasuredCompression);
    }
#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
    QCBOREncode_CloseArray(&EncodeCtx);
    QCBOREncode_AddBoolToMapSZ(&EncodeCtx, "Turbo", pEngine->bTurboCharged);
    QCBOREncode_CloseMap(&EncodeCtx);

    /* Get the pointer and length of the encoded output. If there was
     * any encoding error, it will be returned here */
    UsefulBufC EncodedCBOR;
    QCBORError uErr;
    uErr = QCBOREncode_Finish(&EncodeCtx, &EncodedCBOR);
    if(uErr != QCBOR_SUCCESS) {
       return NULLUsefulBufC;
    } else {
       return EncodedCBOR;
    }
}


/**
 * Error results when decoding an Engine data structure.
 */
typedef enum  {
    EngineSuccess,
    CBORNotWellFormed,
    TooManyCylinders,
    EngineProtocolerror,
    WrongNumberOfCylinders
} EngineDecodeErrors;


/**
 * Convert @ref QCBORError to @ref EngineDecodeErrors.
 */
static EngineDecodeErrors ConvertError(QCBORError uErr)
{
    EngineDecodeErrors uReturn;

    switch(uErr)
    {
        case QCBOR_SUCCESS:
            uReturn = EngineSuccess;
            break;

        case QCBOR_ERR_HIT_END:
            uReturn = CBORNotWellFormed;
            break;

        default:
            uReturn = EngineProtocolerror;
            break;
    }

    return uReturn;
}


/**
 * @brief Simplest engine decode using spiffy decode features.
 *
 * @param[in] EncodedEngine  Pointer and length of CBOR-encoded engine.
 * @param[out] pE            The structure filled in from the decoding.
 *
 * @return The decode error or success.
 *
 * This decodes the CBOR into the engine structure.
 *
 * As QCBOR automatically supports both definite and indefinite maps
 * and arrays, this will decode either.
 *
 * This uses QCBOR's spiffy decode functions, so the implementation is
 * simple and closely parallels the encode implementation in
 * EncodeEngineDefiniteLength().
 *
 * Another way to decode without using spiffy decode functions is to
 * use QCBORDecode_GetNext() to traverse the whole tree.  This
 * requires a more complex implementation, but is faster and will pull
 * in less code from the CBOR library. The speed advantage is likely
 * of consequence when decoding much much larger CBOR on slow small
 * CPUs.
 *
 * A middle way is to use the spiffy decode
 * QCBORDecode_GetItemsInMap().  The implementation has middle
 * complexity and uses less CPU.
 */
EngineDecodeErrors DecodeEngineSpiffy(UsefulBufC EncodedEngine, CarEngine *pE)
{
    QCBORError         uErr;
    QCBORDecodeContext DecodeCtx;

    /* Let QCBORDecode internal error tracking do its work. */
    QCBORDecode_Init(&DecodeCtx, EncodedEngine, QCBOR_DECODE_MODE_NORMAL);
    QCBORDecode_EnterMap(&DecodeCtx, NULL);
    QCBORDecode_GetTextStringInMapSZ(&DecodeCtx, "Manufacturer", &(pE->Manufacturer));
    QCBORDecode_GetInt64InMapSZ(&DecodeCtx, "Displacement", &(pE->uDisplacement));
    QCBORDecode_GetInt64InMapSZ(&DecodeCtx, "Horsepower", &(pE->uHorsePower));
#ifndef USEFULBUF_DISABLE_ALL_FLOAT
    QCBORDecode_GetDoubleInMapSZ(&DecodeCtx, "DesignedCompression", &(pE->dDesignedCompresion));
#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
    QCBORDecode_GetBoolInMapSZ(&DecodeCtx, "Turbo", &(pE->bTurboCharged));

    QCBORDecode_GetInt64InMapSZ(&DecodeCtx, "NumCylinders", &(pE->uNumCylinders));

    /* Check the internal tracked error now before going on to
     * reference any of the decoded data, particularly
     * pE->uNumCylinders */
    uErr = QCBORDecode_GetError(&DecodeCtx);
    if(uErr != QCBOR_SUCCESS) {
        goto Done;
    }

    if(pE->uNumCylinders > MAX_CYLINDERS) {
        return TooManyCylinders;
    }

    QCBORDecode_EnterArrayFromMapSZ(&DecodeCtx, "Cylinders");
#ifndef USEFULBUF_DISABLE_ALL_FLOAT
    for(int64_t i = 0; i < pE->uNumCylinders; i++) {
        QCBORDecode_GetDouble(&DecodeCtx,
                              &(pE->cylinders[i].dMeasuredCompression));
    }
#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
    QCBORDecode_ExitArray(&DecodeCtx);
    QCBORDecode_ExitMap(&DecodeCtx);

    /* Catch further decoding error here */
    uErr = QCBORDecode_Finish(&DecodeCtx);

Done:
    return ConvertError(uErr);
}


int32_t RunQCborExample(void)
{
   CarEngine                 InitialEngine;
   CarEngine                 DecodedEngine;

   /* For every buffer used by QCBOR a pointer and a length are always
    * carried in a UsefulBuf. This is a secure coding and hygene
    * practice to help make sure code never runs off the end of a
    * buffer.
    *
    * UsefulBuf structures are passed as a stack parameter to make the
    * code prettier. The object code generated isn't much different
    * from passing a pointer parameter and a length parameter.
    *
    * This macro is equivalent to:
    *    uint8_t    __pBufEngineBuffer[300];
    *    UsefulBuf  EngineBuffer = {__pBufEngineBuffer, 300};
    */
   UsefulBuf_MAKE_STACK_UB(  EngineBuffer, 300);

   /* The pointer in UsefulBuf is not const and used for representing
    * a buffer to be written to. For UsefulbufC, the pointer is const
    * and is used to represent a buffer that has been written to.
    */
   UsefulBufC                EncodedEngine;
   EngineDecodeErrors        uErr;

   /* Initialize the structure with some values. */
   EngineInit(&InitialEngine);

   /* Encode the engine structure. */
   EncodedEngine = EncodeEngine(&InitialEngine, EngineBuffer);
   if(UsefulBuf_IsNULLC(EncodedEngine)) {
      printf("Engine encode failed\n");
      goto Done;
   }
   printf("Example: Definite Length Engine Encoded in %zu bytes\n",
          EncodedEngine.len);

   /* Decode the CBOR */
   uErr = DecodeEngineSpiffy(EncodedEngine, &DecodedEngine);
   printf("Example: Spiffy Engine Decode Result: %d\n", uErr);
   if(uErr) {
      goto Done;
   }

   /* Check the results */
   if(!EngineCompare(&InitialEngine, &DecodedEngine)) {
      printf("Example: Spiffy Engine Decode comparison fail\n");
   }


   /* Further example of how to calculate the encoded size, then allocate */
   UsefulBufC EncodedEngineSize;
   EncodedEngineSize = EncodeEngine(&InitialEngine, SizeCalculateUsefulBuf);
   if(UsefulBuf_IsNULLC(EncodedEngine)) {
      printf("Engine encode size calculation failed\n");
      goto Done;
   }
   (void)EncodedEngineSize; /* Supress unsed variable warning */
   /* Here malloc could be called to allocate a buffer. Then
    * EncodeEngine() can be called a second time to actually
    * encode. (The actual code is not live here to avoid a
    * dependency on malloc()).
    *  UsefulBuf  MallocedBuffer;
    *  MallocedBuffer.len = EncodedEngineSize.len;
    *  MallocedBuffer.ptr = malloc(EncodedEngineSize.len);
    *  EncodedEngine = EncodeEngine(&InitialEngine, MallocedBuffer);
    */

Done:
   printf("\n");

   return 0;
}
