/*
 * AWS IoT Jobs V1.0.0
 * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/**
 * @file aws_iot_jobs_serialize.c
 * @brief Implements functions that generate and parse Jobs JSON documents.
 */

/* The config header is always included first. */
#include "iot_config.h"

/* Standard includes. */
#include <stdio.h>
#include <string.h>

/* Jobs internal include. */
#include "private/aws_iot_jobs_internal.h"

/* Error handling include. */
#include "iot_error.h"

/* JSON utilities include. */
#include "aws_iot_doc_parser.h"

/**
 * @brief Minimum length of a Jobs request.
 *
 * At the very least, the request will contain: {"clientToken":""}
 */
#define MINIMUM_REQUEST_LENGTH                    ( AWS_IOT_CLIENT_TOKEN_KEY_LENGTH + 7 )

/**
 * @brief The length of client tokens generated by this library.
 */
#define CLIENT_TOKEN_AUTOGENERATE_LENGTH          ( 8 )

/**
 * @brief JSON key representing Jobs status.
 */
#define STATUS_KEY                                "status"

/**
 * @brief Length of #STATUS_KEY.
 */
#define STATUS_KEY_LENGTH                         ( sizeof( STATUS_KEY ) - 1 )

/**
 * @brief JSON key representing Jobs status details.
 */
#define STATUS_DETAILS_KEY                        "statusDetails"

/**
 * @brief Length of #STATUS_DETAILS_KEY.
 */
#define STATUS_DETAILS_KEY_LENGTH                 ( sizeof( STATUS_DETAILS_KEY ) - 1 )

/**
 * @brief JSON key representing Jobs expected version.
 */
#define EXPECTED_VERSION_KEY                      "expectedVersion"

/**
 * @brief Length of #EXPECTED_VERSION_KEY.
 */
#define EXPECTED_VERSION_KEY_LENGTH               ( sizeof( EXPECTED_VERSION_KEY ) - 1 )

/**
 * @brief Maximum length of the expected version when represented as a string.
 *
 * The expected version is a 32-bit unsigned integer. This can be represented in
 * 10 digits plus a NULL-terminator.
 */
#define EXPECTED_VERSION_STRING_LENGTH            ( 11 )

/**
 * @brief JSON key representing Jobs step timeout.
 */
#define STEP_TIMEOUT_KEY                          "stepTimeoutInMinutes"

/**
 * @brief Length of #STEP_TIMEOUT_KEY.
 */
#define STEP_TIMEOUT_KEY_LENGTH                   ( sizeof( STEP_TIMEOUT_KEY ) - 1 )

/**
 * @brief Maximum length of the step timeout when represented as a string.
 *
 * The step timeout is in the range of [-1,10080]. This can be represented as
 * 5 digits plus a NULL-terminator.
 */
#define STEP_TIMEOUT_STRING_LENGTH                ( 6 )

/**
 * @brief JSON key representing the "include Job document" flag.
 */
#define INCLUDE_JOB_DOCUMENT_KEY                  "includeJobDocument"

/**
 * @brief JSON key representing the "include Job Execution state" flag.
 */
#define INCLUDE_JOB_EXECUTION_STATE_KEY           "includeJobExecutionState"

/**
 * @brief Length of #INCLUDE_JOB_EXECUTION_STATE_KEY.
 */
#define INCLUDE_JOB_EXECUTION_STATE_KEY_LENGTH    ( sizeof( INCLUDE_JOB_EXECUTION_STATE_KEY ) - 1 )

/**
 * @brief Length of #INCLUDE_JOB_DOCUMENT_KEY.
 */
#define INCLUDE_JOB_DOCUMENT_KEY_LENGTH           ( sizeof( INCLUDE_JOB_DOCUMENT_KEY ) - 1 )

/**
 * @brief JSON key representing the Jobs execution number.
 */
#define EXECUTION_NUMBER_KEY                      "executionNumber"

/**
 * @brief Length of #EXECUTION_NUMBER_KEY.
 */
#define EXECUTION_NUMBER_KEY_LENGTH               ( sizeof( EXECUTION_NUMBER_KEY ) - 1 )

/**
 * @brief Maximum length of the execution number when represented as a string.
 *
 * The execution number is a 32-bit integer. This can be represented in 10 digits,
 * plus 1 for a possible negative sign, plus a NULL-terminator.
 */
#define EXECUTION_NUMBER_STRING_LENGTH            ( 12 )

/**
 * @brief JSON key representing Jobs error code in error responses.
 */
#define CODE_KEY                                  "code"

/**
 * @brief Length of #CODE_KEY.
 */
#define CODE_KEY_LENGTH                           ( sizeof( CODE_KEY ) - 1 )

/**
 * @brief Append a string to a buffer.
 *
 * Also updates `copyOffset` with `stringLength`.
 *
 * @param[in] pBuffer Start of a buffer.
 * @param[in] copyOffset Offset in `pBuffer` where `pString` will be placed.
 * @param[in] pString The string to append.
 * @param[in] stringLength Length of `pString`.
 */
#define APPEND_STRING( pBuffer, copyOffset, pString, stringLength ) \
    ( void ) memcpy( pBuffer + copyOffset, pString, stringLength ); \
    copyOffset += ( size_t ) stringLength;

/*-----------------------------------------------------------*/

/**
 * @brief Place a JSON boolean flag in the given buffer.
 *
 * @param[in] pBuffer The buffer where the flag is placed.
 * @param[in] copyOffset Offset in `pBuffer` where the flag is placed.
 * @param[in] pFlagName Either #INCLUDE_JOB_DOCUMENT_KEY or #INCLUDE_JOB_EXECUTION_STATE_KEY.
 * @param[in] flagNameLength Either #INCLUDE_JOB_EXECUTION_STATE_KEY_LENGTH or
 * #INCLUDE_JOB_EXECUTION_STATE_KEY_LENGTH
 * @param[in] value Either `true` or `false`.
 *
 * @warning This function does not check the length of `pBuffer`! Any provided
 * buffer must be large enough to accommodate the flag and value.
 *
 * @return A value of `copyOffset` after the flag.
 */
static size_t _appendFlag( char * pBuffer,
                           size_t copyOffset,
                           const char * pFlagName,
                           size_t flagNameLength,
                           bool value );

/**
 * @brief Place Job status details in the given buffer.
 *
 * @param[in] pBuffer The buffer where the status details are placed.
 * @param[in] copyOffset Offset in `pBuffer` where the status details are placed.
 * @param[in] pStatusDetails The status details to place in the buffer.
 * @param[in] statusDetailsLength Length of `pStatusDetails`.
 *
 * @warning This function does not check the length of `pBuffer`! Any provided
 * buffer must be large enough to accommodate the status details.
 *
 * @return A value of `copyOffset` after the status details.
 */
static size_t _appendStatusDetails( char * pBuffer,
                                    size_t copyOffset,
                                    const char * pStatusDetails,
                                    size_t statusDetailsLength );

/**
 * @brief Place Job execution number in the given buffer.
 *
 * @param[in] pBuffer The buffer where the execution number is placed.
 * @param[in] copyOffset Offset in `pBuffer` where the execution number is placed.
 * @param[in] pExecutionNumber The execution number to place in the buffer.
 * @param[in] executionNumberLength Length of `pExecutionNumber`.
 *
 * @warning This function does not check the length of `pBuffer`! Any provided
 * buffer must be large enough to accommodate the execution number.
 *
 * @return A value of `copyOffset` after the execution number.
 */
static size_t _appendExecutionNumber( char * pBuffer,
                                      size_t copyOffset,
                                      const char * pExecutionNumber,
                                      size_t executionNumberLength );

/**
 * @brief Place Job step timeout in the given buffer.
 *
 * @param[in] pBuffer The buffer where the step timeout is placed.
 * @param[in] copyOffset Offset in `pBuffer` where the step timeout is placed.
 * @param[in] pStepTimeout The step timeout to place in the buffer.
 * @param[in] stepTimeoutLength Length of `pStepTimeout`.
 *
 * @warning This function does not check the length of `pBuffer`! Any provided
 * buffer must be large enough to accommodate the step timeout.
 *
 * @return A value of `copyOffset` after the step timeout.
 */
static size_t _appendStepTimeout( char * pBuffer,
                                  size_t copyOffset,
                                  const char * pStepTimeout,
                                  size_t stepTimeoutLength );

/**
 * @brief Place a client token in the given buffer.
 *
 * @param[in] pBuffer The buffer where the client token is placed.
 * @param[in] copyOffset Offset in `pBuffer` where client token is placed.
 * @param[in] pRequestInfo Contains information on a client token to place.
 * @param[out] pOperation Location and length of client token are written here.
 *
 * @warning This function does not check the length of `pBuffer`! Any provided
 * buffer must be large enough to accommodate #CLIENT_TOKEN_AUTOGENERATE_LENGTH
 * characters.
 *
 * @return A value of `copyOffset` after the client token.
 */
static size_t _appendClientToken( char * pBuffer,
                                  size_t copyOffset,
                                  const AwsIotJobsRequestInfo_t * pRequestInfo,
                                  _jobsOperation_t * pOperation );

/**
 * @brief Generates a request JSON for a GET PENDING operation.
 *
 * @param[in] pRequestInfo Common Jobs request parameters.
 * @param[in] pOperation Operation associated with the Jobs request.
 *
 * @return #AWS_IOT_JOBS_SUCCESS or #AWS_IOT_JOBS_NO_MEMORY
 */
static AwsIotJobsError_t _generateGetPendingRequest( const AwsIotJobsRequestInfo_t * pRequestInfo,
                                                     _jobsOperation_t * pOperation );

/**
 * @brief Generates a request JSON for a START NEXT operation.
 *
 * @param[in] pRequestInfo Common Jobs request parameters.
 * @param[in] pUpdateInfo Jobs update parameters.
 * @param[in] pOperation Operation associated with the Jobs request.
 *
 * @return #AWS_IOT_JOBS_SUCCESS or #AWS_IOT_JOBS_NO_MEMORY
 */
static AwsIotJobsError_t _generateStartNextRequest( const AwsIotJobsRequestInfo_t * pRequestInfo,
                                                    const AwsIotJobsUpdateInfo_t * pUpdateInfo,
                                                    _jobsOperation_t * pOperation );

/**
 * @brief Generates a request JSON for a DESCRIBE operation.
 *
 * @param[in] pRequestInfo Common jobs request parameters.
 * @param[in] executionNumber Job execution number to include in request.
 * @param[in] includeJobDocument Whether the response should include the Job document.
 * @param[in] pOperation Operation associated with the Jobs request.
 *
 * @return #AWS_IOT_JOBS_SUCCESS or #AWS_IOT_JOBS_NO_MEMORY.
 */
static AwsIotJobsError_t _generateDescribeRequest( const AwsIotJobsRequestInfo_t * pRequestInfo,
                                                   int32_t executionNumber,
                                                   bool includeJobDocument,
                                                   _jobsOperation_t * pOperation );

/**
 * @brief Generates a request JSON for an UPDATE operation.
 *
 * @param[in] pRequestInfo Common Jobs request parameters.
 * @param[in] pUpdateInfo Jobs update parameters.
 * @param[in] pOperation Operation associated with the Jobs request.
 */
static AwsIotJobsError_t _generateUpdateRequest( const AwsIotJobsRequestInfo_t * pRequestInfo,
                                                 const AwsIotJobsUpdateInfo_t * pUpdateInfo,
                                                 _jobsOperation_t * pOperation );

/**
 * @brief Parse an error from a Jobs error document.
 *
 * @param[in] pErrorDocument Jobs error document.
 * @param[in] errorDocumentLength Length of `pErrorDocument`.
 *
 * @return A Jobs error code between #AWS_IOT_JOBS_INVALID_TOPIC and
 * #AWS_IOT_JOBS_TERMINAL_STATE.
 */
static AwsIotJobsError_t _parseErrorDocument( const char * pErrorDocument,
                                              size_t errorDocumentLength );

/*-----------------------------------------------------------*/

static size_t _appendFlag( char * pBuffer,
                           size_t copyOffset,
                           const char * pFlagName,
                           size_t flagNameLength,
                           bool value )
{
    if( value == true )
    {
        APPEND_STRING( pBuffer,
                       copyOffset,
                       pFlagName,
                       flagNameLength );
        APPEND_STRING( pBuffer, copyOffset, "\":true,\"", 8 );
    }
    else
    {
        APPEND_STRING( pBuffer,
                       copyOffset,
                       pFlagName,
                       flagNameLength );
        APPEND_STRING( pBuffer, copyOffset, "\":false,\"", 9 );
    }

    return copyOffset;
}

/*-----------------------------------------------------------*/

static size_t _appendStatusDetails( char * pBuffer,
                                    size_t copyOffset,
                                    const char * pStatusDetails,
                                    size_t statusDetailsLength )
{
    APPEND_STRING( pBuffer, copyOffset, STATUS_DETAILS_KEY, STATUS_DETAILS_KEY_LENGTH );
    APPEND_STRING( pBuffer, copyOffset, "\":", 2 );
    APPEND_STRING( pBuffer,
                   copyOffset,
                   pStatusDetails,
                   statusDetailsLength );
    APPEND_STRING( pBuffer, copyOffset, ",\"", 2 );

    return copyOffset;
}

/*-----------------------------------------------------------*/

static size_t _appendExecutionNumber( char * pBuffer,
                                      size_t copyOffset,
                                      const char * pExecutionNumber,
                                      size_t executionNumberLength )
{
    APPEND_STRING( pBuffer,
                   copyOffset,
                   EXECUTION_NUMBER_KEY,
                   EXECUTION_NUMBER_KEY_LENGTH );
    APPEND_STRING( pBuffer,
                   copyOffset,
                   "\":",
                   2 );
    APPEND_STRING( pBuffer,
                   copyOffset,
                   pExecutionNumber,
                   executionNumberLength );
    APPEND_STRING( pBuffer, copyOffset, ",\"", 2 );

    return copyOffset;
}

/*-----------------------------------------------------------*/

static size_t _appendStepTimeout( char * pBuffer,
                                  size_t copyOffset,
                                  const char * pStepTimeout,
                                  size_t stepTimeoutLength )
{
    APPEND_STRING( pBuffer,
                   copyOffset,
                   STEP_TIMEOUT_KEY,
                   STEP_TIMEOUT_KEY_LENGTH );
    APPEND_STRING( pBuffer, copyOffset, "\":", 2 );
    APPEND_STRING( pBuffer, copyOffset, pStepTimeout, stepTimeoutLength );
    APPEND_STRING( pBuffer, copyOffset, ",\"", 2 );

    return copyOffset;
}

/*-----------------------------------------------------------*/

static size_t _appendClientToken( char * pBuffer,
                                  size_t copyOffset,
                                  const AwsIotJobsRequestInfo_t * pRequestInfo,
                                  _jobsOperation_t * pOperation )
{
    int clientTokenLength = 0;
    uint32_t clientToken = 0;

    /* Place the client token key in the buffer. */
    APPEND_STRING( pBuffer,
                   copyOffset,
                   AWS_IOT_CLIENT_TOKEN_KEY,
                   AWS_IOT_CLIENT_TOKEN_KEY_LENGTH );
    APPEND_STRING( pBuffer, copyOffset, "\":\"", 3 );

    /* Set the pointer to the client token. */
    pOperation->pClientToken = pBuffer + copyOffset - 1;

    if( pRequestInfo->pClientToken == AWS_IOT_JOBS_CLIENT_TOKEN_AUTOGENERATE )
    {
        /* Take the address of the given buffer, truncated to 8 characters. This
         * provides a client token that is very likely to be unique while in use. */
        clientToken = ( uint32_t ) ( ( uint64_t ) pBuffer % 100000000ULL );

        clientTokenLength = snprintf( pBuffer + copyOffset,
                                      CLIENT_TOKEN_AUTOGENERATE_LENGTH + 1,
                                      "%08u", clientToken );
        AwsIotJobs_Assert( clientTokenLength == CLIENT_TOKEN_AUTOGENERATE_LENGTH );

        copyOffset += ( size_t ) clientTokenLength;
        pOperation->clientTokenLength = CLIENT_TOKEN_AUTOGENERATE_LENGTH + 2;
    }
    else
    {
        APPEND_STRING( pBuffer,
                       copyOffset,
                       pRequestInfo->pClientToken,
                       pRequestInfo->clientTokenLength );

        pOperation->clientTokenLength = pRequestInfo->clientTokenLength + 2;
    }

    return copyOffset;
}

/*-----------------------------------------------------------*/

static AwsIotJobsError_t _generateGetPendingRequest( const AwsIotJobsRequestInfo_t * pRequestInfo,
                                                     _jobsOperation_t * pOperation )
{
    IOT_FUNCTION_ENTRY( AwsIotJobsError_t, AWS_IOT_JOBS_SUCCESS );
    char * pJobsRequest = NULL;
    size_t copyOffset = 0;
    size_t requestLength = MINIMUM_REQUEST_LENGTH;

    /* Add the length of the client token. */
    if( pRequestInfo->pClientToken != AWS_IOT_JOBS_CLIENT_TOKEN_AUTOGENERATE )
    {
        AwsIotJobs_Assert( pRequestInfo->clientTokenLength > 0 );

        requestLength += pRequestInfo->clientTokenLength;
    }
    else
    {
        requestLength += CLIENT_TOKEN_AUTOGENERATE_LENGTH;
    }

    /* Allocate memory for the request JSON. */
    pJobsRequest = AwsIotJobs_MallocString( requestLength );

    if( pJobsRequest == NULL )
    {
        IotLogError( "No memory for Jobs GET PENDING request." );

        IOT_SET_AND_GOTO_CLEANUP( AWS_IOT_JOBS_NO_MEMORY );
    }

    /* Clear the request JSON. */
    ( void ) memset( pJobsRequest, 0x00, requestLength );

    /* Construct the request JSON, which consists of just a clientToken key. */
    APPEND_STRING( pJobsRequest, copyOffset, "{\"", 2 );
    copyOffset = _appendClientToken( pJobsRequest, copyOffset, pRequestInfo, pOperation );
    APPEND_STRING( pJobsRequest, copyOffset, "\"}", 2 );

    /* Set the output parameters. */
    pOperation->pJobsRequest = pJobsRequest;
    pOperation->jobsRequestLength = requestLength;

    /* Ensure offsets are valid. */
    AwsIotJobs_Assert( copyOffset == requestLength );
    AwsIotJobs_Assert( pOperation->pClientToken > pOperation->pJobsRequest );
    AwsIotJobs_Assert( pOperation->pClientToken <
                       pOperation->pJobsRequest + pOperation->jobsRequestLength );

    IotLogDebug( "Jobs GET PENDING request: %.*s",
                 pOperation->jobsRequestLength,
                 pOperation->pJobsRequest );

    IOT_FUNCTION_EXIT_NO_CLEANUP();
}

/*-----------------------------------------------------------*/

static AwsIotJobsError_t _generateStartNextRequest( const AwsIotJobsRequestInfo_t * pRequestInfo,
                                                    const AwsIotJobsUpdateInfo_t * pUpdateInfo,
                                                    _jobsOperation_t * pOperation )
{
    IOT_FUNCTION_ENTRY( AwsIotJobsError_t, AWS_IOT_JOBS_SUCCESS );
    char * pJobsRequest = NULL;
    size_t copyOffset = 0;
    size_t requestLength = MINIMUM_REQUEST_LENGTH;
    char pStepTimeout[ STEP_TIMEOUT_STRING_LENGTH ] = { 0 };
    int stepTimeoutLength = 0;

    /* Add the length of status details if provided. */
    if( pUpdateInfo->pStatusDetails != AWS_IOT_JOBS_NO_STATUS_DETAILS )
    {
        /* Add 4 for the 2 quotes, colon, and comma. */
        requestLength += STATUS_DETAILS_KEY_LENGTH + 4;
        requestLength += pUpdateInfo->statusDetailsLength;
    }

    if( pUpdateInfo->stepTimeoutInMinutes != AWS_IOT_JOBS_NO_TIMEOUT )
    {
        /* Calculate the length of the step timeout. Add 4 for the 2 quotes, colon, and comma. */
        requestLength += STEP_TIMEOUT_KEY_LENGTH + 4;

        if( pUpdateInfo->stepTimeoutInMinutes == AWS_IOT_JOBS_CANCEL_TIMEOUT )
        {
            /* Step timeout will be set to -1. */
            pStepTimeout[ 0 ] = '-';
            pStepTimeout[ 1 ] = '1';
            stepTimeoutLength = 2;
        }
        else
        {
            /* Convert the step timeout to a string. */
            stepTimeoutLength = snprintf( pStepTimeout,
                                          STEP_TIMEOUT_STRING_LENGTH,
                                          "%d",
                                          pUpdateInfo->stepTimeoutInMinutes );
            AwsIotJobs_Assert( stepTimeoutLength > 0 );
            AwsIotJobs_Assert( stepTimeoutLength < STEP_TIMEOUT_STRING_LENGTH );
        }

        requestLength += ( size_t ) stepTimeoutLength;
    }

    /* Add the length of the client token. */
    if( pRequestInfo->pClientToken != AWS_IOT_JOBS_CLIENT_TOKEN_AUTOGENERATE )
    {
        AwsIotJobs_Assert( pRequestInfo->clientTokenLength > 0 );

        requestLength += pRequestInfo->clientTokenLength;
    }
    else
    {
        requestLength += CLIENT_TOKEN_AUTOGENERATE_LENGTH;
    }

    /* Allocate memory for the request JSON. */
    pJobsRequest = AwsIotJobs_MallocString( requestLength );

    if( pJobsRequest == NULL )
    {
        IotLogError( "No memory for Jobs START NEXT request." );

        IOT_SET_AND_GOTO_CLEANUP( AWS_IOT_JOBS_NO_MEMORY );
    }

    /* Clear the request JSON. */
    ( void ) memset( pJobsRequest, 0x00, requestLength );

    /* Construct the request JSON. */
    APPEND_STRING( pJobsRequest, copyOffset, "{\"", 2 );

    /* Add status details if present. */
    if( pUpdateInfo->pStatusDetails != AWS_IOT_JOBS_NO_STATUS_DETAILS )
    {
        copyOffset = _appendStatusDetails( pJobsRequest,
                                           copyOffset,
                                           pUpdateInfo->pStatusDetails,
                                           pUpdateInfo->statusDetailsLength );
    }

    /* Add step timeout if present. */
    if( pUpdateInfo->stepTimeoutInMinutes != AWS_IOT_JOBS_NO_TIMEOUT )
    {
        copyOffset = _appendStepTimeout( pJobsRequest,
                                         copyOffset,
                                         pStepTimeout,
                                         stepTimeoutLength );
    }

    /* Add client token. */
    copyOffset = _appendClientToken( pJobsRequest, copyOffset, pRequestInfo, pOperation );

    APPEND_STRING( pJobsRequest, copyOffset, "\"}", 2 );

    /* Set the output parameters. */
    pOperation->pJobsRequest = pJobsRequest;
    pOperation->jobsRequestLength = requestLength;

    /* Ensure offsets are valid. */
    AwsIotJobs_Assert( copyOffset == requestLength );
    AwsIotJobs_Assert( pOperation->pClientToken > pOperation->pJobsRequest );
    AwsIotJobs_Assert( pOperation->pClientToken <
                       pOperation->pJobsRequest + pOperation->jobsRequestLength );

    IotLogDebug( "Jobs START NEXT request: %.*s",
                 pOperation->jobsRequestLength,
                 pOperation->pJobsRequest );

    IOT_FUNCTION_EXIT_NO_CLEANUP();
}

/*-----------------------------------------------------------*/

static AwsIotJobsError_t _generateDescribeRequest( const AwsIotJobsRequestInfo_t * pRequestInfo,
                                                   int32_t executionNumber,
                                                   bool includeJobDocument,
                                                   _jobsOperation_t * pOperation )
{
    IOT_FUNCTION_ENTRY( AwsIotJobsError_t, AWS_IOT_JOBS_SUCCESS );
    char * pJobsRequest = NULL;
    size_t copyOffset = 0;
    size_t requestLength = MINIMUM_REQUEST_LENGTH;
    char pExecutionNumber[ EXECUTION_NUMBER_STRING_LENGTH ] = { 0 };
    int executionNumberLength = 0;

    /* Add the "include job document" flag if false. The default value is true,
     * so the flag is not needed if true. */
    if( includeJobDocument == false )
    {
        /* Add the length of "includeJobDocument" plus 4 for 2 quotes, a colon,
         * and a comma. */
        requestLength += INCLUDE_JOB_DOCUMENT_KEY_LENGTH + 4;

        /* Add the length of "false". */
        requestLength += 5;
    }

    /* Add the length of the execution number if present. */
    if( executionNumber != AWS_IOT_JOBS_NO_EXECUTION_NUMBER )
    {
        /* Convert the execution number to a string. */
        executionNumberLength = snprintf( pExecutionNumber,
                                          EXECUTION_NUMBER_STRING_LENGTH,
                                          "%d",
                                          executionNumber );
        AwsIotJobs_Assert( executionNumberLength > 0 );
        AwsIotJobs_Assert( executionNumberLength < EXECUTION_NUMBER_STRING_LENGTH );

        requestLength += EXECUTION_NUMBER_KEY_LENGTH + 4;
        requestLength += ( size_t ) executionNumberLength;
    }

    /* Add the length of the client token. */
    if( pRequestInfo->pClientToken != AWS_IOT_JOBS_CLIENT_TOKEN_AUTOGENERATE )
    {
        AwsIotJobs_Assert( pRequestInfo->clientTokenLength > 0 );

        requestLength += pRequestInfo->clientTokenLength;
    }
    else
    {
        requestLength += CLIENT_TOKEN_AUTOGENERATE_LENGTH;
    }

    /* Allocate memory for the request JSON. */
    pJobsRequest = AwsIotJobs_MallocString( requestLength );

    if( pJobsRequest == NULL )
    {
        IotLogError( "No memory for Jobs DESCRIBE request." );

        IOT_SET_AND_GOTO_CLEANUP( AWS_IOT_JOBS_NO_MEMORY );
    }

    /* Clear the request JSON. */
    ( void ) memset( pJobsRequest, 0x00, requestLength );

    /* Construct the request JSON. */
    APPEND_STRING( pJobsRequest, copyOffset, "{\"", 2 );

    /* Add the "include job document" flag if false. */
    if( includeJobDocument == false )
    {
        copyOffset = _appendFlag( pJobsRequest,
                                  copyOffset,
                                  INCLUDE_JOB_DOCUMENT_KEY,
                                  INCLUDE_JOB_DOCUMENT_KEY_LENGTH,
                                  false );
    }

    /* Add the length of the execution number if present. */
    if( executionNumber != AWS_IOT_JOBS_NO_EXECUTION_NUMBER )
    {
        copyOffset = _appendExecutionNumber( pJobsRequest,
                                             copyOffset,
                                             pExecutionNumber,
                                             ( size_t ) executionNumberLength );
    }

    /* Add client token. */
    copyOffset = _appendClientToken( pJobsRequest, copyOffset, pRequestInfo, pOperation );

    APPEND_STRING( pJobsRequest, copyOffset, "\"}", 2 );

    /* Set the output parameters. */
    pOperation->pJobsRequest = pJobsRequest;
    pOperation->jobsRequestLength = requestLength;

    /* Ensure offsets are valid. */
    AwsIotJobs_Assert( copyOffset == requestLength );
    AwsIotJobs_Assert( pOperation->pClientToken > pOperation->pJobsRequest );
    AwsIotJobs_Assert( pOperation->pClientToken <
                       pOperation->pJobsRequest + pOperation->jobsRequestLength );

    IotLogDebug( "Jobs DESCRIBE request: %.*s",
                 pOperation->jobsRequestLength,
                 pOperation->pJobsRequest );

    IOT_FUNCTION_EXIT_NO_CLEANUP();
}

/*-----------------------------------------------------------*/

static AwsIotJobsError_t _generateUpdateRequest( const AwsIotJobsRequestInfo_t * pRequestInfo,
                                                 const AwsIotJobsUpdateInfo_t * pUpdateInfo,
                                                 _jobsOperation_t * pOperation )
{
    IOT_FUNCTION_ENTRY( AwsIotJobsError_t, AWS_IOT_JOBS_SUCCESS );
    char * pJobsRequest = NULL;
    size_t copyOffset = 0;
    size_t requestLength = MINIMUM_REQUEST_LENGTH;
    const char * pStatus = NULL;
    size_t statusLength = 0;
    char pExpectedVersion[ EXPECTED_VERSION_STRING_LENGTH ] = { 0 };
    char pExecutionNumber[ EXECUTION_NUMBER_STRING_LENGTH ] = { 0 };
    char pStepTimeout[ STEP_TIMEOUT_STRING_LENGTH ] = { 0 };
    int expectedVersionLength = 0, executionNumberLength = 0, stepTimeoutLength = 0;

    /* Determine the status string and length to report to the Jobs service.
     * Add 6 for the 4 quotes, colon, and comma. */
    requestLength += STATUS_KEY_LENGTH + 6;

    switch( pUpdateInfo->newStatus )
    {
        case AWS_IOT_JOB_STATE_IN_PROGRESS:
            pStatus = "IN_PROGRESS";
            break;

        case AWS_IOT_JOB_STATE_FAILED:
            pStatus = "FAILED";
            break;

        case AWS_IOT_JOB_STATE_SUCCEEDED:
            pStatus = "SUCCEEDED";
            break;

        default:
            /* The only remaining valid state is REJECTED. */
            AwsIotJobs_Assert( pUpdateInfo->newStatus == AWS_IOT_JOB_STATE_REJECTED );
            pStatus = "REJECTED";
            break;
    }

    statusLength = strlen( pStatus );
    requestLength += statusLength;

    /* Add the length of status details if provided. */
    if( pUpdateInfo->pStatusDetails != AWS_IOT_JOBS_NO_STATUS_DETAILS )
    {
        /* Add 4 for the 2 quotes, colon, and comma. */
        requestLength += STATUS_DETAILS_KEY_LENGTH + 4;
        requestLength += pUpdateInfo->statusDetailsLength;
    }

    /* Add the expected version if provided. */
    if( pUpdateInfo->expectedVersion != AWS_IOT_JOBS_NO_VERSION )
    {
        /* Convert the expected version to a string. */
        expectedVersionLength = snprintf( pExpectedVersion,
                                          EXPECTED_VERSION_STRING_LENGTH,
                                          "%u",
                                          pUpdateInfo->expectedVersion );
        AwsIotJobs_Assert( expectedVersionLength > 0 );
        AwsIotJobs_Assert( expectedVersionLength < EXPECTED_VERSION_STRING_LENGTH );

        /* Add 6 for the 4 quotes, colon, and comma. */
        requestLength += EXPECTED_VERSION_KEY_LENGTH + 6;
        requestLength += ( size_t ) expectedVersionLength;
    }

    /* Add the length of the execution number if present. */
    if( pUpdateInfo->executionNumber != AWS_IOT_JOBS_NO_EXECUTION_NUMBER )
    {
        /* Convert the execution number to a string. */
        executionNumberLength = snprintf( pExecutionNumber,
                                          EXECUTION_NUMBER_STRING_LENGTH,
                                          "%d",
                                          pUpdateInfo->executionNumber );
        AwsIotJobs_Assert( executionNumberLength > 0 );
        AwsIotJobs_Assert( executionNumberLength < EXECUTION_NUMBER_STRING_LENGTH );

        requestLength += EXECUTION_NUMBER_KEY_LENGTH + 4;
        requestLength += ( size_t ) executionNumberLength;
    }

    /* Add the flags if true. The default values are false, so the flags are not
     * needed if false. */
    if( pUpdateInfo->includeJobExecutionState == true )
    {
        /* Add the length of "includeJobExecutionState" plus 4 for 2 quotes, a colon,
         * and a comma. */
        requestLength += INCLUDE_JOB_EXECUTION_STATE_KEY_LENGTH + 4;

        /* Add the length of "true". */
        requestLength += 4;
    }

    if( pUpdateInfo->includeJobDocument == true )
    {
        /* Add the length of "includeJobDocument" plus 4 for 2 quotes, a colon,
         * and a comma. */
        requestLength += INCLUDE_JOB_DOCUMENT_KEY_LENGTH + 4;

        /* Add the length of "true". */
        requestLength += 4;
    }

    /* Add the step timeout if provided. */
    if( pUpdateInfo->stepTimeoutInMinutes != AWS_IOT_JOBS_NO_TIMEOUT )
    {
        /* Calculate the length of the step timeout. Add 4 for the 2 quotes, colon, and comma. */
        requestLength += STEP_TIMEOUT_KEY_LENGTH + 4;

        if( pUpdateInfo->stepTimeoutInMinutes == AWS_IOT_JOBS_CANCEL_TIMEOUT )
        {
            /* Step timeout will be set to -1. */
            pStepTimeout[ 0 ] = '-';
            pStepTimeout[ 1 ] = '1';
            stepTimeoutLength = 2;
        }
        else
        {
            /* Convert the step timeout to a string. */
            stepTimeoutLength = snprintf( pStepTimeout,
                                          STEP_TIMEOUT_STRING_LENGTH,
                                          "%d",
                                          pUpdateInfo->stepTimeoutInMinutes );
            AwsIotJobs_Assert( stepTimeoutLength > 0 );
            AwsIotJobs_Assert( stepTimeoutLength < STEP_TIMEOUT_STRING_LENGTH );
        }

        requestLength += ( size_t ) stepTimeoutLength;
    }

    /* Add the length of the client token. */
    if( pRequestInfo->pClientToken != AWS_IOT_JOBS_CLIENT_TOKEN_AUTOGENERATE )
    {
        AwsIotJobs_Assert( pRequestInfo->clientTokenLength > 0 );

        requestLength += pRequestInfo->clientTokenLength;
    }
    else
    {
        requestLength += CLIENT_TOKEN_AUTOGENERATE_LENGTH;
    }

    /* Allocate memory for the request JSON. */
    pJobsRequest = AwsIotJobs_MallocString( requestLength );

    if( pJobsRequest == NULL )
    {
        IotLogError( "No memory for Jobs UPDATE request." );

        IOT_SET_AND_GOTO_CLEANUP( AWS_IOT_JOBS_NO_MEMORY );
    }

    /* Clear the request JSON. */
    ( void ) memset( pJobsRequest, 0x00, requestLength );

    /* Construct the request JSON. */
    APPEND_STRING( pJobsRequest, copyOffset, "{\"", 2 );

    /* Add the status. */
    APPEND_STRING( pJobsRequest, copyOffset, STATUS_KEY, STATUS_KEY_LENGTH );
    APPEND_STRING( pJobsRequest, copyOffset, "\":\"", 3 );
    APPEND_STRING( pJobsRequest, copyOffset, pStatus, statusLength );
    APPEND_STRING( pJobsRequest, copyOffset, "\",\"", 3 );

    /* Add status details if present. */
    if( pUpdateInfo->pStatusDetails != AWS_IOT_JOBS_NO_STATUS_DETAILS )
    {
        copyOffset = _appendStatusDetails( pJobsRequest,
                                           copyOffset,
                                           pUpdateInfo->pStatusDetails,
                                           pUpdateInfo->statusDetailsLength );
    }

    /* Add expected version. */
    if( pUpdateInfo->expectedVersion != AWS_IOT_JOBS_NO_VERSION )
    {
        APPEND_STRING( pJobsRequest,
                       copyOffset,
                       EXPECTED_VERSION_KEY,
                       EXPECTED_VERSION_KEY_LENGTH );
        APPEND_STRING( pJobsRequest, copyOffset, "\":\"", 3 );
        APPEND_STRING( pJobsRequest, copyOffset, pExpectedVersion, expectedVersionLength );
        APPEND_STRING( pJobsRequest, copyOffset, "\",\"", 3 );
    }

    /* Add execution number. */
    if( pUpdateInfo->executionNumber != AWS_IOT_JOBS_NO_EXECUTION_NUMBER )
    {
        copyOffset = _appendExecutionNumber( pJobsRequest,
                                             copyOffset,
                                             pExecutionNumber,
                                             executionNumberLength );
    }

    /* Add flags if not default values. */
    if( pUpdateInfo->includeJobExecutionState == true )
    {
        copyOffset = _appendFlag( pJobsRequest,
                                  copyOffset,
                                  INCLUDE_JOB_EXECUTION_STATE_KEY,
                                  INCLUDE_JOB_EXECUTION_STATE_KEY_LENGTH,
                                  true );
    }

    if( pUpdateInfo->includeJobDocument == true )
    {
        copyOffset = _appendFlag( pJobsRequest,
                                  copyOffset,
                                  INCLUDE_JOB_DOCUMENT_KEY,
                                  INCLUDE_JOB_DOCUMENT_KEY_LENGTH,
                                  true );
    }

    /* Add step timeout if provided. */
    if( pUpdateInfo->stepTimeoutInMinutes != AWS_IOT_JOBS_NO_TIMEOUT )
    {
        copyOffset = _appendStepTimeout( pJobsRequest,
                                         copyOffset,
                                         pStepTimeout,
                                         stepTimeoutLength );
    }

    /* Add the client token. */
    copyOffset = _appendClientToken( pJobsRequest, copyOffset, pRequestInfo, pOperation );

    APPEND_STRING( pJobsRequest, copyOffset, "\"}", 2 );

    /* Set the output parameters. */
    pOperation->pJobsRequest = pJobsRequest;
    pOperation->jobsRequestLength = requestLength;

    /* Ensure offsets are valid. */
    AwsIotJobs_Assert( copyOffset == requestLength );
    AwsIotJobs_Assert( pOperation->pClientToken > pOperation->pJobsRequest );
    AwsIotJobs_Assert( pOperation->pClientToken <
                       pOperation->pJobsRequest + pOperation->jobsRequestLength );

    IotLogDebug( "Jobs UPDATE request: %.*s",
                 pOperation->jobsRequestLength,
                 pOperation->pJobsRequest );

    IOT_FUNCTION_EXIT_NO_CLEANUP();
}

/*-----------------------------------------------------------*/

static AwsIotJobsError_t _parseErrorDocument( const char * pErrorDocument,
                                              size_t errorDocumentLength )
{
    IOT_FUNCTION_ENTRY( AwsIotJobsError_t, AWS_IOT_JOBS_STATUS_PENDING );
    const char * pCode = NULL;
    size_t codeLength = 0;

    /* Find the error code. */
    if( AwsIotDocParser_FindValue( pErrorDocument,
                                   errorDocumentLength,
                                   CODE_KEY,
                                   CODE_KEY_LENGTH,
                                   &pCode,
                                   &codeLength ) == false )
    {
        IOT_SET_AND_GOTO_CLEANUP( AWS_IOT_JOBS_BAD_RESPONSE );
    }

    /* Match the JSON error code to a Jobs return value. Assume invalid status
     * unless matched.*/
    status = AWS_IOT_JOBS_BAD_RESPONSE;

    switch( codeLength )
    {
        /* InvalidJson */
        case 13:

            if( strncmp( "\"InvalidJson\"", pCode, codeLength ) == 0 )
            {
                status = AWS_IOT_JOBS_INVALID_JSON;
            }

            break;

        /* InvalidTopic */
        case 14:

            if( strncmp( "\"InvalidTopic\"", pCode, codeLength ) == 0 )
            {
                status = AWS_IOT_JOBS_INVALID_TOPIC;
            }

            break;

        /* InternalError */
        case 15:

            if( strncmp( "\"InternalError\"", pCode, codeLength ) == 0 )
            {
                status = AWS_IOT_JOBS_INTERNAL_ERROR;
            }

            break;

        /* InvalidRequest */
        case 16:

            if( strncmp( "\"InvalidRequest\"", pCode, codeLength ) == 0 )
            {
                status = AWS_IOT_JOBS_INVALID_REQUEST;
            }

            break;

        /* VersionMismatch */
        case 17:

            if( strncmp( "\"VersionMismatch\"", pCode, codeLength ) == 0 )
            {
                status = AWS_IOT_JOBS_VERSION_MISMATCH;
            }

            break;

        /* ResourceNotFound, RequestThrottled */
        case 18:

            if( strncmp( "\"ResourceNotFound\"", pCode, codeLength ) == 0 )
            {
                status = AWS_IOT_JOBS_NOT_FOUND;
            }
            else if( strncmp( "\"RequestThrottled\"", pCode, codeLength ) == 0 )
            {
                status = AWS_IOT_JOBS_THROTTLED;
            }

            break;

        /* TerminalStateReached */
        case 22:

            if( strncmp( "\"TerminalStateReached\"", pCode, codeLength ) == 0 )
            {
                status = AWS_IOT_JOBS_TERMINAL_STATE;
            }

            break;

        /* InvalidStateTransition */
        case 24:

            if( strncmp( "\"InvalidStateTransition\"", pCode, codeLength ) == 0 )
            {
                status = AWS_IOT_JOBS_INVALID_STATE;
            }

            break;

        default:
            break;
    }

    IOT_FUNCTION_EXIT_NO_CLEANUP();
}

/*-----------------------------------------------------------*/

AwsIotJobsError_t _AwsIotJobs_GenerateJsonRequest( _jobsOperationType_t type,
                                                   const AwsIotJobsRequestInfo_t * pRequestInfo,
                                                   const _jsonRequestContents_t * pRequestContents,
                                                   _jobsOperation_t * pOperation )
{
    AwsIotJobsError_t status = AWS_IOT_JOBS_STATUS_PENDING;

    /* Generate request based on the Job operation type. */
    switch( type )
    {
        case JOBS_GET_PENDING:
            status = _generateGetPendingRequest( pRequestInfo, pOperation );
            break;

        case JOBS_START_NEXT:
            status = _generateStartNextRequest( pRequestInfo,
                                                pRequestContents->pUpdateInfo,
                                                pOperation );
            break;

        case JOBS_DESCRIBE:
            status = _generateDescribeRequest( pRequestInfo,
                                               pRequestContents->describe.executionNumber,
                                               pRequestContents->describe.includeJobDocument,
                                               pOperation );
            break;

        default:
            /* The only remaining valid type is UPDATE. */
            AwsIotJobs_Assert( type == JOBS_UPDATE );

            status = _generateUpdateRequest( pRequestInfo,
                                             pRequestContents->pUpdateInfo,
                                             pOperation );
            break;
    }

    return status;
}

/*-----------------------------------------------------------*/

void _AwsIotJobs_ParseResponse( AwsIotStatus_t status,
                                const char * pResponse,
                                size_t responseLength,
                                _jobsOperation_t * pOperation )
{
    AwsIotJobs_Assert( pOperation->status == AWS_IOT_JOBS_STATUS_PENDING );

    /* A non-waitable operation can re-use the pointers from the publish info,
     * since those are guaranteed to be in-scope throughout the user callback.
     * But a waitable operation must copy the data from the publish info because
     * AwsIotJobs_Wait may be called after the MQTT library frees the publish
     * info. */
    if( ( pOperation->flags & AWS_IOT_JOBS_FLAG_WAITABLE ) == 0 )
    {
        pOperation->pJobsResponse = pResponse;
        pOperation->jobsResponseLength = responseLength;
    }
    else
    {
        IotLogDebug( "Allocating new buffer for waitable Jobs %s.",
                     _pAwsIotJobsOperationNames[ pOperation->type ] );

        /* Parameter validation should not have allowed a NULL malloc function. */
        AwsIotJobs_Assert( pOperation->mallocResponse != NULL );

        /* Allocate a buffer for the retrieved document. */
        pOperation->pJobsResponse = pOperation->mallocResponse( responseLength );

        if( pOperation->pJobsResponse == NULL )
        {
            IotLogError( "Failed to allocate buffer for retrieved Jobs %s response.",
                         _pAwsIotJobsOperationNames[ pOperation->type ] );

            pOperation->status = AWS_IOT_JOBS_NO_MEMORY;
        }
        else
        {
            /* Copy the response. */
            ( void ) memcpy( ( void * ) pOperation->pJobsResponse, pResponse, responseLength );
            pOperation->jobsResponseLength = responseLength;
        }
    }

    /* Set the status of the Jobs operation. */
    if( pOperation->status == AWS_IOT_JOBS_STATUS_PENDING )
    {
        if( status == AWS_IOT_ACCEPTED )
        {
            pOperation->status = AWS_IOT_JOBS_SUCCESS;
        }
        else
        {
            pOperation->status = _parseErrorDocument( pResponse, responseLength );
        }
    }
}

/*-----------------------------------------------------------*/
