/*
 * FreeRTOS Kernel V10.3.0
 * Copyright (C) 2020 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.
 *
 * http://www.FreeRTOS.org
 * http://aws.amazon.com/freertos
 *
 * 1 tab == 4 spaces!
 */

/* This demo executes Jobs obtained from AWS IoT. An AWS IoT Job is used to define
 * a set of remote operations that are sent to and executed on one or more devices
 * connected to AWS IoT. Please refer to AWS documentation for more information
 * about AWS IoT Jobs.
 * https://docs.aws.amazon.com/iot/latest/developerguide/iot-jobs.html
 *
 * This demo creates a single application task that sets a callback for the
 * jobs/notify-next topic and executes Jobs created from the AWS IoT console or AWS
 * CLI. Please refer to AWS CLI documentation for more information in creating a
 * Job document.
 * https://docs.aws.amazon.com/cli/latest/reference/iot/create-job.html
 *
 * This demo expects Job documents to have an "action" JSON key. Actions can
 * be one "print", "publish", or "exit".
 * Print Jobs log a message to the local console, and must contain a "message",
 * e.g. { "action": "print", "message": "Hello World!" }.
 * Publish Jobs publish a message to an MQTT Topic. The Job document must
 * contain a "message" and "topic" to publish to, e.g.
 * { "action": "publish", "topic": "demo/jobs", "message": "Hello World!" }.
 * The exit Job exits the demo. Sending { "action": "exit" } will end the program.
 */

/* Standard includes. */
#include <string.h>
#include <stdio.h>

/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"

/* FreeRTOS+TCP includes. */
#include "FreeRTOS_IP.h"

/* IoT SDK includes. */
#include "aws_iot_jobs.h"
#include "aws_iot_demo_profile.h"
#include "iot_mqtt.h"
#include "iot_taskpool_freertos.h"
#include "aws_iot_doc_parser.h"
#include "platform/iot_clock.h"
#include "platform/iot_threads.h"
#include "platform/iot_network_freertos.h"

#include "atomic.h"

/* Preprocessor check iot configuration. */
#include "aws_iot_setup_check.h"

/* Demo specific includes. */
#include "demo_config.h"

/*-----------------------------------------------------------*/

/**
 * @brief The keep-alive interval used for this example.
 *
 * An MQTT ping request will be sent periodically at this interval.
 *
 * @note: This value is set to zero to disable MQTT
 * keep alive for the Windows simulator project.
 * The FreeRTOS kernel does not accurately calculate time for the Windows
 * Simulator. Therefore, MQTT PING Request messages may be sent
 * at an incorrect time interval to the broker. If the broker does
 * not receive a ping request within 1.5x the time sent in a
 * connection request, the broker may close the connection.
 * To enable the keep alive feature, set this value
 * to the desired interval in seconds.
 */
#define jobsexampleKEEP_ALIVE_SECONDS          ( 0 )

/**
 * @brief The timeout for MQTT operations in this example.
 */
#define jobsexampleMQTT_TIMEOUT_MS             ( 5000 )

/**
 * @brief Use default timeout when calling AwsIotJobs_Init.
 */
#define jobsexampleUSE_DEFAULT_MQTT_TIMEOUT    ( 0 )

/**
 * @brief The bit which is set in the demo task's notification value from the
 * disconnect callback to inform the demo task about the MQTT disconnect.
 */
#define jobsexampleDISCONNECTED_BIT            ( 1UL << 0UL )

/**
 * @brief The bit which is set in the demo task's notification value from the
 * operation complete callback to inform the demo task to exit.
 */
#define jobsexampleEXIT_BIT                    ( 1UL << 1UL )

/**
 * @brief Length of the client identifier for this demo.
 */
#define jobsexampleCLIENT_IDENTIFIER_LENGTH    ( sizeof( awsiotdemoprofileCLIENT_IDENTIFIER ) - 1 )

/**
 * @brief The JSON key of the Job ID.
 *
 * Job documents are in JSON documents received from the AWS IoT Jobs service.
 * All such JSON documents will contain this key, whose value represents the unique
 * identifier of a Job.
 */
#define jobsexampleID_KEY                      "jobId"

/**
 * @brief The length of #jobsexampleID_KEY.
 */
#define jobsexampleID_KEY_LENGTH               ( sizeof( jobsexampleID_KEY ) - 1 )

/**
 * @brief The JSON key of the Job document.
 *
 * Job documents are in JSON documents received from the AWS IoT Jobs service.
 * All such JSON documents will contain this key, whose value is an application-specific
 * Job document.
 */
#define jobsexampleDOC_KEY                     "jobDocument"

/**
 * @brief The length of #jobsexampleDOC_KEY.
 */
#define jobsexampleDOC_KEY_LENGTH              ( sizeof( jobsexampleDOC_KEY ) - 1 )

/**
 * @brief The JSON key whose value represents the action this demo should take.
 *
 * This demo program expects this key to be in the Job document. It is a key
 * specific to this demo.
 */
#define jobsexampleACTION_KEY                  "action"

/**
 * @brief The length of #jobsexampleACTION_KEY.
 */
#define jobsexampleACTION_KEY_LENGTH           ( sizeof( jobsexampleACTION_KEY ) - 1 )

/**
 * @brief A message associated with the Job action.
 *
 * This demo program expects this key to be in the Job document if the "action"
 * is either "publish" or "print". It represents the message that should be
 * published or printed, respectively.
 */
#define jobsexampleMESSAGE_KEY                 "message"

/**
 * @brief The length of #jobsexampleMESSAGE_KEY.
 */
#define jobsexampleMESSAGE_KEY_LENGTH          ( sizeof( jobsexampleMESSAGE_KEY ) - 1 )

/**
 * @brief An MQTT topic associated with the Job "publish" action.
 *
 * This demo program expects this key to be in the Job document if the "action"
 * is "publish". It represents the MQTT topic on which the message should be
 * published.
 */
#define jobsexampleTOPIC_KEY                   "topic"

/**
 * @brief The length of #jobsexampleTOPIC_KEY.
 */
#define jobsexampleTOPIC_KEY_LENGTH            ( sizeof( jobsexampleTOPIC_KEY ) - 1 )

/**
 * @brief The minimum length of a string in a JSON Job document.
 *
 * At the very least the Job ID must have the quotes that identify it as a JSON
 * string and 1 character for the string itself (the string must not be empty).
 */
#define jobsexampleJSON_STRING_MIN_LENGTH      ( ( size_t ) 3 )

/**
 * @brief The maximum length of a Job ID.
 *
 * This limit is defined by AWS service limits. See the following page for more
 * information.
 *
 * https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html#job-limits
 */
#define jobsexampleID_MAX_LENGTH               ( ( size_t ) 64 )

/**
 * @brief A value passed as context to #prvOperationCompleteCallback to specify that
 * it should notify the demo task of an exit request.
 */
#define jobsexampleSHOULD_EXIT                 ( ( void * ) ( ( intptr_t ) 1 ) )

/**
 * @brief Time to wait before exiting demo.
 *
 * The milliseconds to wait before exiting. This is because the MQTT Broker
 * will disconnect us if we are idle too long, and we have disabled keep alive.
 */
#define jobsexampleMS_BEFORE_EXIT              ( 10 * 60 * 1000 )

/*-----------------------------------------------------------*/

/**
 * @brief Currently supported actions that a Job document can specify.
 */
typedef enum _jobAction
{
	JOB_ACTION_PRINT,   /**< Print a message. */
	JOB_ACTION_PUBLISH, /**< Publish a message to an MQTT topic. */
	JOB_ACTION_EXIT,    /**< Exit the demo. */
	JOB_ACTION_UNKNOWN  /**< Unknown action. */
} _jobAction_t;

/**
 * @brief The task used to demonstrate Jobs.
 *
 * @param[in] pvParameters Parameters as passed at the time of task creation. Not
 * used in this example.
 */
static void prvJobsDemoTask( void * pvParameters );

/**
 * @brief The callback invoked by the MQTT library when the MQTT connection gets
 * disconnected.
 *
 * @param[in] pvCallbackContext Callback context as provided at the time of
 * connect.
 * @param[in] pxCallbackParams Contains the reason why the MQTT connection was
 * disconnected.
 */
static void prvExample_OnDisconnect( void * pvCallbackContext,
									 IotMqttCallbackParam_t * pxCallbackParams );

/**
 * @brief Connects to the MQTT broker as specified in awsiotdemoprofileAWS_ENDPOINT
 * and awsiotdemoprofileAWS_MQTT_PORT.
 */
static void prvMQTTConnect( void );

/**
 * @brief Disconnects from the MQTT broker gracefully by sending an MQTT
 * DISCONNECT message.
 */
static void prvMQTTDisconnect( void );

/**
 * @brief Set callback for publishes to the jobs/notify-next topic.
 */
static void prvSetNotifyNextCallback( void );

/**
 * @brief Converts a string in a Job document to a #_jobAction_t.
 *
 * @param[in] pcAction The Job action as a string.
 * @param[in] xActionLength The length of `pcAction`.
 *
 * @return A #_jobAction_t equivalent to the given string.
 */
static _jobAction_t prvGetAction( const char * pcAction,
								  size_t xActionLength );

/**
 * @brief Extracts a JSON string from the Job document.
 *
 * @param[in] pcJsonDoc The JSON document to search.
 * @param[in] xJsonDocLength Length of `pcJsonDoc`.
 * @param[in] pcKey The JSON key to search for.
 * @param[in] xKeyLength Length of `pcKey`.
 * @param[out] ppcValue The extracted JSON value.
 * @param[out] pxValueLength Length of ppcValue.
 *
 * @return `pdTRUE` if the key was found and the value is valid; `pdFALSE` otherwise.
 */
static BaseType_t prvGetJsonString( const char * pcJsonDoc,
									size_t xJsonDocLength,
									const char * pcKey,
									size_t xKeyLength,
									const char ** ppcValue,
									size_t * pxValueLength );

/**
 * @brief Job operation completion callback. This function is invoked when an
 * asynchronous Job operation finishes.
 *
 * @param[in] pvCallbackContext Set to a non-NULL value to exit the demo.
 * @param[in] pxCallbackParam Information on the Job operation that completed.
 */
static void prvOperationCompleteCallback( void * pvCallbackContext,
										  AwsIotJobsCallbackParam_t * pxCallbackParam );


/**
 * @brief Process an action with a message, such as "print" or "publish".
 *
 * @param[in] xMqttConnection The MQTT connection to use if the action is "publish".
 * @param[in] xAction Either #JOB_ACTION_PRINT or #JOB_ACTION_PUBLISH.
 * @param[in] pcJobDoc A pointer to the Job document.
 * @param[in] xJobDocLength The length of the Job document.
 *
 * @return #AWS_IOT_JOB_STATE_SUCCEEDED on success; #AWS_IOT_JOB_STATE_FAILED otherwise.
 */
static AwsIotJobState_t prvProcessMessage( IotMqttConnection_t xMqttConnection,
										   _jobAction_t xAction,
										   const char * pcJobDoc,
										   size_t xJobDocLength );

/**
 * @brief Process a Job received from the Notify Next callback.
 *
 * @param[in] pxJobInfo The parameter to the Notify Next callback that contains
 * information about the received Job.
 * @param[in] pcJobId A pointer to the Job ID.
 * @param[in] xJobIdLength The length of the Job ID.
 * @param[in] pcJobDoc A pointer to the Job document.
 * @param[in] xJobDocLength The length of the Job document.
 */
static void prvProcessJob( const AwsIotJobsCallbackParam_t * pxJobInfo,
						   const char * pcJobId,
						   size_t xJobIdLength,
						   const char * pcJobDoc,
						   size_t xJobDocLength );

/**
 * @brief Jobs Notify Next callback. This function is invoked when a new Job is
 * received from the Jobs service.
 *
 * @param[in] pCallbackContext Ignored.
 * @param[in] pxCallbackInfo Contains the received Job.
 */
static void prvJobsCallback( void * pCallbackContext,
							 AwsIotJobsCallbackParam_t * pxCallbackInfo );

/*-----------------------------------------------------------*/

/**
 * @brief The MQTT connection handle used in this example.
 */
static IotMqttConnection_t xMQTTConnection = IOT_MQTT_CONNECTION_INITIALIZER;

/*
 * @brief The main task handle in this demo.
 */
static TaskHandle_t xMainTaskHandle;

/**
 * @brief Parameters used to create the system task pool.
 */
static const IotTaskPoolInfo_t xTaskPoolParameters =
{
	/* Minimum number of threads in a task pool.
	 * Note the slimmed down version of the task
	 * pool used by this library does not auto-scale
	 * the number of tasks in the pool so in this
	 * case this sets the number of tasks in the
	 * pool. */
	1,

	/* Maximum number of threads in a task pool.
	 * Note the slimmed down version of the task
	 * pool used by this library does not auto-scale
	 * the number of tasks in the pool so in this
	 * case this parameter is just ignored. */
	1,

	/* Stack size for every task pool thread - in
	 * bytes, hence multiplying by the number of bytes
	 * in a word as configMINIMAL_STACK_SIZE is
	 * specified in words. */
	configMINIMAL_STACK_SIZE * sizeof( portSTACK_TYPE ),
	/* Priority for every task pool thread. */
	tskIDLE_PRIORITY,
};

/***************** Structures that define the connection. *********************/


static const struct IotNetworkServerInfo xMQTTBrokerInfo =
{
	.pHostName = awsiotdemoprofileAWS_ENDPOINT,
	.port = awsiotdemoprofileAWS_MQTT_PORT
};

static struct IotNetworkCredentials xNetworkSecurityCredentials =
{
	/* Optional TLS extensions. For this demo, they are disabled. */
	.pAlpnProtos = NULL,
	.maxFragmentLength = 0,

	/* SNI is enabled by default. */
	.disableSni = false,

	/* Provide the certificate for validating the server. Only required for
	demos using TLS. */
	.pRootCa = awsiotdemoprofileAWS_CERTIFICATE_PEM,
	.rootCaSize = sizeof( awsiotdemoprofileAWS_CERTIFICATE_PEM ),

	/* Strong mutual authentication to authenticate both the broker and
	 * the client. */
	.pClientCert = awsiotdemoprofileCLIENT_CERTIFICATE_PEM,
	.clientCertSize = sizeof( awsiotdemoprofileCLIENT_CERTIFICATE_PEM ),
	.pPrivateKey = awsiotdemoprofileCLIENT_PRIVATE_KEY_PEM,
	.privateKeySize = sizeof( awsiotdemoprofileCLIENT_PRIVATE_KEY_PEM )
};

static IotMqttNetworkInfo_t xNetworkInfo =
{
	/* No connection to the MQTT broker has been established yet and we want to
	 * establish a new connection. */
	.createNetworkConnection = true,
	.u.setup.pNetworkServerInfo = &( xMQTTBrokerInfo ),

	/* Set the TLS credentials for the new MQTT connection. */
	.u.setup.pNetworkCredentialInfo = &xNetworkSecurityCredentials,

	/* Use FreeRTOS+TCP network interface. */
	.pNetworkInterface = IOT_NETWORK_INTERFACE_FREERTOS,

	/* Setup the callback which is called when the MQTT connection is
	 * disconnected. The task handle is passed as the callback context which
	 * is used by the callback to send a task notification to this task.*/
	.disconnectCallback.function = prvExample_OnDisconnect
};

static const IotMqttConnectInfo_t xConnectInfo =
{
	/* Set this flag to true if connecting to the AWS IoT MQTT broker. */
	.awsIotMqttMode = false,

	/* Start with a clean session i.e. direct the MQTT broker to discard any
	 * previous session data. Also, establishing a connection with clean session
	 * will ensure that the broker does not store any data when this client
	 * gets disconnected. */
	.cleanSession = true,

	/* Since we are starting with a clean session, there are no previous
	 * subscriptions to be restored. */
	.pPreviousSubscriptions = NULL,
	.previousSubscriptionCount = 0,

	/* We do not want to publish Last Will and Testament (LWT) message if the
	 * client gets disconnected. */
	.pWillInfo = NULL,

	/* Send an MQTT PING request every minute to keep the connection open if
	 * there is no other MQTT traffic. */
	.keepAliveSeconds = jobsexampleKEEP_ALIVE_SECONDS,

	/* The client identifier is used to uniquely identify this MQTT client to
	 * the MQTT broker.  In a production device the identifier can be something
	 * unique, such as a device serial number. */
	.pClientIdentifier = awsiotdemoprofileCLIENT_IDENTIFIER,
	.clientIdentifierLength = ( uint16_t ) sizeof( awsiotdemoprofileCLIENT_IDENTIFIER ) - 1,

	/* This example does not authenticate the client and therefore username and
	 * password fields are not used. */
	.pUserName = NULL,
	.userNameLength = 0,
	.pPassword = NULL,
	.passwordLength = 0
};
/*-----------------------------------------------------------*/

static void prvExample_OnDisconnect( void * pvCallbackContext,
									 IotMqttCallbackParam_t * pxCallbackParams )
{
TaskHandle_t xDemoTaskHandle = ( TaskHandle_t ) pvCallbackContext;

	/* Ensure that we initiated the disconnect. */
	configASSERT( pxCallbackParams->u.disconnectReason == IOT_MQTT_DISCONNECT_CALLED );

	/* Inform the demo task about the disconnect. */
	xTaskNotify( xDemoTaskHandle,
				 jobsexampleDISCONNECTED_BIT,
				 eSetBits /* Set the jobsexampleDISCONNECTED_BIT in the demo task's notification value. */
				 );
}
/*-----------------------------------------------------------*/

void vStartJobsDemo( void )
{
TickType_t xShortDelay = ( TickType_t ) pdMS_TO_TICKS( ( TickType_t ) 500 );

	/* Wait a short time to allow receipt of the ARP replies. */
	vTaskDelay( xShortDelay );

	/* This example uses a single application task, which in turn is used to
	 * connect, subscribe, publish, unsubscribe and disconnect from the MQTT
	 * broker. */
	xTaskCreate( prvJobsDemoTask,		  /* Function that implements the task. */
				 "JobsDemo",			   /* Text name for the task - only used for debugging. */
				 democonfigDEMO_STACKSIZE, /* Size of stack (in words, not bytes) to allocate for the task. */
				 NULL,					 /* Task parameter - not used in this case. */
				 tskIDLE_PRIORITY,		 /* Task priority, must be between 0 and configMAX_PRIORITIES - 1. */
				 NULL );				   /* Used to pass out a handle to the created task - not used in this case. */
}
/*-----------------------------------------------------------*/

static void prvJobsDemoTask( void * pvParameters )
{
IotMqttError_t xResult;
IotNetworkError_t xNetworkInit;
uint32_t ulNotificationValue = 0;
const TickType_t xNoDelay = ( TickType_t ) 0;
AwsIotJobsError_t xStatus = AWS_IOT_JOBS_SUCCESS;
AwsIotJobsCallbackInfo_t xCallbackInfo = AWS_IOT_JOBS_CALLBACK_INFO_INITIALIZER;
AwsIotJobsRequestInfo_t xRequestInfo = AWS_IOT_JOBS_REQUEST_INFO_INITIALIZER;

	/* Remove compiler warnings about unused parameters. */
	( void ) pvParameters;

	xMainTaskHandle = xTaskGetCurrentTaskHandle();

	/* The MQTT library needs a task pool, so create the system task pool. */
	xResult = IotTaskPool_CreateSystemTaskPool( &( xTaskPoolParameters ) );
	configASSERT( xResult == IOT_TASKPOOL_SUCCESS );

	/* Initialize the network stack abstraction for FreeRTOS. */
	xNetworkInit = IotNetworkFreeRTOS_Init();
	configASSERT( xNetworkInit == IOT_NETWORK_SUCCESS );

	/* MQTT library must be initialized before it can be used. This is just one
	 * time initialization. */
	xResult = IotMqtt_Init();
	configASSERT( xResult == IOT_MQTT_SUCCESS );

	/* Initialize Jobs library. */
	xResult = AwsIotJobs_Init( jobsexampleUSE_DEFAULT_MQTT_TIMEOUT );
	configASSERT( xResult == AWS_IOT_JOBS_SUCCESS );

	/****************************** Connect. ******************************/

	/* Establish a connection to the AWS IoT MQTT broker. This example connects to
	 * the MQTT broker as specified in awsiotdemoprofileAWS_ENDPOINT and
	 * awsiotdemoprofileAWS_MQTT_PORT at the top of this file.
	 */
	configPRINTF( ( "Attempt to connect to %s\r\n", awsiotdemoprofileAWS_ENDPOINT ) );
	prvMQTTConnect();
	configPRINTF( ( "Connected to %s\r\n", awsiotdemoprofileAWS_ENDPOINT ) );

	/* Don't expect any notifications to be pending yet. */
	configASSERT( ulTaskNotifyTake( pdTRUE, xNoDelay ) == 0 );

	configPRINTF( ( "Setting callback for jobs/notify-next\r\n" ) );
	prvSetNotifyNextCallback();

	/* Call DescribeAsync to see if there are any pending jobs. */
	xRequestInfo.mqttConnection = xMQTTConnection;
	xRequestInfo.pThingName = awsiotdemoprofileCLIENT_IDENTIFIER;
	xRequestInfo.thingNameLength = jobsexampleCLIENT_IDENTIFIER_LENGTH;
	xRequestInfo.pJobId = AWS_IOT_JOBS_NEXT_JOB;
	xRequestInfo.jobIdLength = AWS_IOT_JOBS_NEXT_JOB_LENGTH;

	/* Use the same callback as notify-next so any pending jobs will be
	 * executed the same way. */
	xCallbackInfo.function = prvJobsCallback;

	xStatus = AwsIotJobs_DescribeAsync( &xRequestInfo, AWS_IOT_JOBS_NO_EXECUTION_NUMBER, true, 0, &xCallbackInfo, NULL );
	configPRINTF( ( "Describe queued with result %s.\r\n", AwsIotJobs_strerror( xStatus ) ) );

	/* Print out a short user guide to the console. The default logging
	 * limit of 255 characters can be changed in demo_logging.c, but breaking
	 * up the only instance of a 1000+ character string is more practical. */
	configPRINTF( (
					  "\r\n"
					  "/*-----------------------------------------------------------*/\r\n"
					  "\r\n"
					  "The Jobs demo is now ready to accept Jobs.\r\n"
					  "Jobs may be created using the AWS IoT console or AWS CLI.\r\n"
					  "See the following link for more information.\r\n"
					  "\r\n" ) );
	configPRINTF( (
					  "\r"
					  "https://docs.aws.amazon.com/cli/latest/reference/iot/create-job.html\r\n"
					  "\r\n"
					  "This demo expects Job documents to have an \"action\" JSON key.\r\n"
					  "The following actions are currently supported:\r\n" ) );
	configPRINTF( (
					  "\r"
					  " - print          \r\n"
					  "   Logs a message to the local console. The Job document must also contain a \"message\".\r\n"
					  "   For example: { \"action\": \"print\", \"message\": \"Hello world!\"} will cause\r\n"
					  "   \"Hello world!\" to be printed on the console.\r\n" ) );
	configPRINTF( (
					  "\r"
					  " - publish        \r\n"
					  "   Publishes a message to an MQTT topic. The Job document must also contain a \"message\" and \"topic\".\r\n" ) );
	configPRINTF( (
					  "\r"
					  "   For example: { \"action\": \"publish\", \"topic\": \"demo/jobs\", \"message\": \"Hello world!\"} will cause\r\n"
					  "   \"Hello world!\" to be published to the topic \"demo/jobs\".\r\n" ) );
	configPRINTF( (
					  "\r"
					  " - exit           \r\n"
					  "   Exits the demo program. This program will run until { \"action\": \"exit\" } is received.\r\n"
					  "\r\n"
					  "/*-----------------------------------------------------------*/\r\n" ) );

	/* Wait for an exit job to be received. If an exit job is not received within
	 * jobsexampleMS_BEFORE_EXIT, exit anyway. This is because we have disabled
	 * keep-alive, and the server will disconnect as after some time. */
	xTaskNotifyWait( 0UL,					   /* Don't clear any bits on entry. */
					 jobsexampleEXIT_BIT,	   /* Clear bit on exit. */
					 &( ulNotificationValue ), /* Obtain the notification value. */
					 pdMS_TO_TICKS( jobsexampleMS_BEFORE_EXIT) );
	/* Check was due to receiving an exit job. */
	if( ( ulNotificationValue & jobsexampleEXIT_BIT ) != jobsexampleEXIT_BIT )
	{
		configPRINTF( ( "Disconnecting as %u milliseconds have elapsed.\r\n", jobsexampleMS_BEFORE_EXIT ) );
	}

	/* Disconnect MQTT gracefully. */
	prvMQTTDisconnect();
	configPRINTF( ( "Disconnected from %s\r\n\r\n", awsiotdemoprofileAWS_ENDPOINT ) );

	/* Wait for the disconnect operation to complete which is informed to us
	 * by the disconnect callback (prvExample_OnDisconnect)by setting
	 * the jobsexampleDISCONNECTED_BIT in this task's notification value. */
	xTaskNotifyWait( 0UL,						  /* Don't clear any bits on entry. */
					 jobsexampleDISCONNECTED_BIT, /* Clear bit on exit. */
					 &( ulNotificationValue ),	  /* Obtain the notification value. */
					 pdMS_TO_TICKS( jobsexampleMQTT_TIMEOUT_MS ) );
	configASSERT( ( ulNotificationValue & jobsexampleDISCONNECTED_BIT ) == jobsexampleDISCONNECTED_BIT );

	configPRINTF( ( "prvJobsDemoTask() completed successfully. Total free heap is %u\r\n", xPortGetFreeHeapSize() ) );
	configPRINTF( ( "Demo completed successfully.\r\n" ) );

	/* Clean up initialized libraries. */
	AwsIotJobs_Cleanup();
	IotMqtt_Cleanup();
	IotNetworkFreeRTOS_Cleanup();

	/* FreeRTOS Tasks must _vTaskDelete( NULL )_ before exiting the function. */
	vTaskDelete( NULL );
}
/*-----------------------------------------------------------*/

static void prvMQTTConnect( void )
{
IotMqttError_t xResult;

	/* Set the context to pass into the disconnect callback function. */
	xNetworkInfo.disconnectCallback.pCallbackContext = ( void * ) xTaskGetCurrentTaskHandle();

	/* Establish the connection to the MQTT broker - It is a blocking call and
	 * will return only when connection is complete or a timeout occurs. */
	xResult = IotMqtt_Connect( &( xNetworkInfo ),
							   &( xConnectInfo ),
							   jobsexampleMQTT_TIMEOUT_MS,
							   &( xMQTTConnection ) );
	configASSERT( xResult == IOT_MQTT_SUCCESS );
}
/*-----------------------------------------------------------*/

static void prvMQTTDisconnect( void )
{
	/* Send a MQTT DISCONNECT packet to the MQTT broker to do a graceful
	 * disconnect. */
	IotMqtt_Disconnect( xMQTTConnection,
						0 /* flags - 0 means a graceful disconnect by sending MQTT DISCONNECT. */
						);
}
/*-----------------------------------------------------------*/

static void prvSetNotifyNextCallback( void )
{
AwsIotJobsError_t xCallbackStatus = AWS_IOT_JOBS_SUCCESS;
AwsIotJobsCallbackInfo_t xCallbackInfo = AWS_IOT_JOBS_CALLBACK_INFO_INITIALIZER;

	/* Set the jobs callback function. */
	xCallbackInfo.function = prvJobsCallback;

	/************************ Set notify-next callbacks **********************/

	xCallbackStatus = AwsIotJobs_SetNotifyNextCallback( xMQTTConnection,
														awsiotdemoprofileCLIENT_IDENTIFIER,
														jobsexampleCLIENT_IDENTIFIER_LENGTH,
														0,
														&xCallbackInfo );

	configASSERT( xCallbackStatus == AWS_IOT_JOBS_SUCCESS );
}
/*-----------------------------------------------------------*/

static _jobAction_t prvGetAction( const char * pcAction,
								  size_t xActionLength )
{
_jobAction_t xAction = JOB_ACTION_UNKNOWN;

	configASSERT( pcAction != NULL );

	if( strncmp( pcAction, "print", xActionLength ) == 0 )
	{
		xAction = JOB_ACTION_PRINT;
	}
	else if( strncmp( pcAction, "publish", xActionLength ) == 0 )
	{
		xAction = JOB_ACTION_PUBLISH;
	}
	else if( strncmp( pcAction, "exit", xActionLength ) == 0 )
	{
		xAction = JOB_ACTION_EXIT;
	}

	return xAction;
}
/*-----------------------------------------------------------*/

static BaseType_t prvGetJsonString( const char * pcJsonDoc,
									size_t xJsonDocLength,
									const char * pcKey,
									size_t xKeyLength,
									const char ** ppcValue,
									size_t * pxValueLength )
{
BaseType_t xKeyFound = pdFALSE;

	configASSERT( pcJsonDoc != NULL );
	configASSERT( pcKey != NULL );

	/*
	 * Note: This parser used is specific for parsing AWS IoT document received
	 * through a mutually authenticated connection. This parser will not check
	 * for the correctness of the document as it is designed for low memory
	 * footprint rather than checking for correctness of the document. This
	 * parser is not meant to be used as a general purpose JSON parser.
	 */
	xKeyFound = ( BaseType_t ) AwsIotDocParser_FindValue(
		pcJsonDoc,
		xJsonDocLength,
		pcKey,
		xKeyLength,
		ppcValue,
		pxValueLength );

	if( xKeyFound == pdTRUE )
	{
		/* Exclude empty strings. */
		if( *pxValueLength < jobsexampleJSON_STRING_MIN_LENGTH )
		{
			xKeyFound = pdFALSE;
		}
		else
		{
			/* Adjust the value to remove the quotes. */
			( *ppcValue )++;
			( *pxValueLength ) -= 2;
		}
	}

	return xKeyFound;
}
/*-----------------------------------------------------------*/

static void prvOperationCompleteCallback( void * pvCallbackContext,
										  AwsIotJobsCallbackParam_t * pxCallbackParam )
{
	configASSERT( pxCallbackParam != NULL );

	/* This function is invoked when either a StartNext or Update completes. */
	if( pxCallbackParam->callbackType == AWS_IOT_JOBS_START_NEXT_COMPLETE )
	{
		configPRINTF( ( "Job StartNext complete with result %s.\r\n",
						AwsIotJobs_strerror( pxCallbackParam->u.operation.result ) ) );
	}
	else
	{
		configPRINTF( ( "Job Update complete with result %s.\r\n",
						AwsIotJobs_strerror( pxCallbackParam->u.operation.result ) ) );
	}

	/* If a non-NULL context is given, set the flag to exit the demo. */
	if( pvCallbackContext != NULL )
	{
		xTaskNotify( xMainTaskHandle,
					 jobsexampleEXIT_BIT,
					 eSetBits /* Set the jobsexampleEXIT_BIT in the demo task's notification value. */
					 );
	}
}
/*-----------------------------------------------------------*/

static AwsIotJobState_t prvProcessMessage( IotMqttConnection_t xMqttConnection,
										   _jobAction_t xAction,
										   const char * pcJobDoc,
										   size_t xJobDocLength )
{
AwsIotJobState_t xStatus = AWS_IOT_JOB_STATE_SUCCEEDED;
IotMqttError_t xMqttStatus = IOT_MQTT_STATUS_PENDING;
IotMqttPublishInfo_t xPublishInfo = IOT_MQTT_PUBLISH_INFO_INITIALIZER;
const char * pcMessage = NULL, * pcTopic = NULL;
size_t xMessageLength = 0, xTopicLength = 0;

	configASSERT( pcJobDoc != NULL );

	/* Both "print" and "publish" require a "message" key. Search the Job
	 * document for this key. */
	if( prvGetJsonString( pcJobDoc,
						  xJobDocLength,
						  jobsexampleMESSAGE_KEY,
						  jobsexampleMESSAGE_KEY_LENGTH,
						  &pcMessage,
						  &xMessageLength ) == pdFALSE )
	{
		configPRINTF( ( "Job document for \"print\" or \"publish\" does not contain a %s key.\r\n",
						jobsexampleMESSAGE_KEY ) );

		xStatus = AWS_IOT_JOB_STATE_FAILED;
	}

	if( xStatus == AWS_IOT_JOB_STATE_SUCCEEDED )
	{
		if( xAction == JOB_ACTION_PRINT )
		{
			/* Print the given message if the action is "print". */
			configPRINTF( (
							  "\r\n"
							  "/*-----------------------------------------------------------*/\r\n"
							  "\r\n"
							  "%.*s\r\n"
							  "\r\n"
							  "/*-----------------------------------------------------------*/\r\n"
							  "\r\n", xMessageLength, pcMessage ) );
		}
		else
		{
			/* Extract the topic if the action is "publish". */
			if( prvGetJsonString( pcJobDoc,
								  xJobDocLength,
								  jobsexampleTOPIC_KEY,
								  jobsexampleTOPIC_KEY_LENGTH,
								  &pcTopic,
								  &xTopicLength ) == pdFALSE )
			{
				configPRINTF( ( "Job document for action \"publish\" does not contain a %s key.\r\n",
								jobsexampleTOPIC_KEY ) );

				xStatus = AWS_IOT_JOB_STATE_FAILED;
			}

			if( xStatus == AWS_IOT_JOB_STATE_SUCCEEDED )
			{
				xPublishInfo.qos = IOT_MQTT_QOS_0;
				xPublishInfo.pTopicName = pcTopic;
				xPublishInfo.topicNameLength = ( uint16_t ) xTopicLength;
				xPublishInfo.pPayload = pcMessage;
				xPublishInfo.payloadLength = xMessageLength;

				xMqttStatus = IotMqtt_PublishAsync( xMqttConnection, &xPublishInfo, 0, NULL, NULL );

				if( xMqttStatus != IOT_MQTT_SUCCESS )
				{
					xStatus = AWS_IOT_JOB_STATE_FAILED;
				}
			}
		}
	}

	return xStatus;
}
/*-----------------------------------------------------------*/

static void prvProcessJob( const AwsIotJobsCallbackParam_t * pxJobInfo,
						   const char * pcJobId,
						   size_t xJobIdLength,
						   const char * pcJobDoc,
						   size_t xJobDocLength )
{
AwsIotJobsError_t xStatus = AWS_IOT_JOBS_SUCCESS;
AwsIotJobsUpdateInfo_t xUpdateInfo = AWS_IOT_JOBS_UPDATE_INFO_INITIALIZER;
AwsIotJobsCallbackInfo_t xCallbackInfo = AWS_IOT_JOBS_CALLBACK_INFO_INITIALIZER;
const char * pcAction = NULL;
size_t xActionLength = 0;
_jobAction_t xAction = JOB_ACTION_UNKNOWN;
AwsIotJobsRequestInfo_t xRequestInfo = AWS_IOT_JOBS_REQUEST_INFO_INITIALIZER;

	configASSERT( pxJobInfo != NULL );
	configASSERT( pcJobId != NULL );
	configASSERT( pcJobDoc != NULL );

	configPRINTF( ( "Job document received: %.*s\r\n", xJobDocLength, pcJobDoc ) );

	xRequestInfo.mqttConnection = pxJobInfo->mqttConnection;
	xRequestInfo.pThingName = pxJobInfo->pThingName;
	xRequestInfo.thingNameLength = pxJobInfo->thingNameLength;
	xRequestInfo.pJobId = pcJobId;
	xRequestInfo.jobIdLength = xJobIdLength;

	/* Tell the Jobs service that the device has started working on the Job.
	 * Use the StartNext API to set the Job's status to IN_PROGRESS. */
	xCallbackInfo.function = prvOperationCompleteCallback;

	xStatus = AwsIotJobs_StartNextAsync( &xRequestInfo, &xUpdateInfo, 0, &xCallbackInfo, NULL );

	configPRINTF( ( "Jobs StartNext queued with result %s.\r\n", AwsIotJobs_strerror( xStatus ) ) );

	/* Get the action for this device. */
	if( prvGetJsonString( pcJobDoc,
						  xJobDocLength,
						  jobsexampleACTION_KEY,
						  jobsexampleACTION_KEY_LENGTH,
						  &pcAction,
						  &xActionLength ) == pdTRUE )
	{
		xAction = prvGetAction( pcAction, xActionLength );

		switch( xAction )
		{
			case JOB_ACTION_EXIT:
				xCallbackInfo.pCallbackContext = jobsexampleSHOULD_EXIT;
				xUpdateInfo.newStatus = AWS_IOT_JOB_STATE_SUCCEEDED;
				break;

			case JOB_ACTION_PRINT:
			case JOB_ACTION_PUBLISH:
				xUpdateInfo.newStatus = prvProcessMessage( pxJobInfo->mqttConnection,
														   xAction,
														   pcJobDoc,
														   xJobDocLength );
				break;

			default:
				configPRINTF( ( "Received Job document with unknown action %.*s.\r\n",
								xActionLength,
								pcAction ) );

				xUpdateInfo.newStatus = AWS_IOT_JOB_STATE_FAILED;
				break;
		}
	}
	else
	{
		configPRINTF( ( "Received Job document does not contain an %s key.\r\n",
						jobsexampleACTION_KEY ) );

		/* The given Job document is not valid for this demo. */
		xUpdateInfo.newStatus = AWS_IOT_JOB_STATE_FAILED;
	}

	configPRINTF( ( "Setting state of %.*s to %s.\r\n",
					xJobIdLength,
					pcJobId,
					AwsIotJobs_StateName( xUpdateInfo.newStatus ) ) );

	/* Tell the Jobs service that the device has finished the Job. */
	xStatus = AwsIotJobs_UpdateAsync( &xRequestInfo, &xUpdateInfo, 0, &xCallbackInfo, NULL );

	configPRINTF( ( "Jobs Update queued with result %s.\r\n", AwsIotJobs_strerror( xStatus ) ) );
}
/*-----------------------------------------------------------*/

static void prvJobsCallback( void * pCallbackContext,
							 AwsIotJobsCallbackParam_t * pxCallbackInfo )
{
BaseType_t xIdKeyFound = pdFALSE, xDocKeyFound = pdFALSE;
const char * pcJobId = NULL;
size_t xJobIdLength = 0;
const char * pcJobDoc = NULL;
size_t xJobDocLength = 0;
const char * pcRawDocument = NULL;
size_t xRawDocumentLength = 0;

	/* Silence warnings about unused parameters. */
	( void ) pCallbackContext;

	configASSERT( pxCallbackInfo != NULL );

	/* Check if this callback was called from a describe operation or
	 * due to notify-next. */
	if( pxCallbackInfo->callbackType == AWS_IOT_JOBS_DESCRIBE_COMPLETE )
	{
		pcRawDocument = pxCallbackInfo->u.operation.pResponse;
		xRawDocumentLength = pxCallbackInfo->u.operation.responseLength;
	}
	else
	{
		pcRawDocument = pxCallbackInfo->u.callback.pDocument;
		xRawDocumentLength = pxCallbackInfo->u.callback.documentLength;
	}

	/* Get the Job ID. */
	xIdKeyFound = prvGetJsonString( pcRawDocument,
									xRawDocumentLength,
									jobsexampleID_KEY,
									jobsexampleID_KEY_LENGTH,
									&pcJobId,
									&xJobIdLength );

	if( xIdKeyFound == pdTRUE )
	{
		if( xJobIdLength > jobsexampleID_MAX_LENGTH )
		{
			configPRINTF( ( "Received Job ID %.*s longer than %lu, which is the "
							"maximum allowed by AWS IoT. Ignoring Job.\r\n",
							xJobIdLength,
							pcJobId,
							( unsigned long ) jobsexampleID_MAX_LENGTH ) );

			xIdKeyFound = pdFALSE;
		}
		else
		{
			configPRINTF( ( "Job %.*s received.\r\n", xJobIdLength, pcJobId ) );
		}
	}

	/* Get the Job document.
	 *
	 * Note: This parser used is specific for parsing AWS IoT document received
	 * through a mutually authenticated connection. This parser will not check
	 * for the correctness of the document as it is designed for low memory
	 * footprint rather than checking for correctness of the document. This
	 * parser is not meant to be used as a general purpose JSON parser.
	 */
	xDocKeyFound = ( BaseType_t ) AwsIotDocParser_FindValue(
		pcRawDocument,
		xRawDocumentLength,
		jobsexampleDOC_KEY,
		jobsexampleDOC_KEY_LENGTH,
		&pcJobDoc,
		&xJobDocLength );

	/* When both the Job ID and Job document are available, process the Job. */
	if( ( xIdKeyFound == pdTRUE ) && ( xDocKeyFound == pdTRUE ) )
	{
		/* Process the Job document. */
		prvProcessJob( pxCallbackInfo,
					   pcJobId,
					   xJobIdLength,
					   pcJobDoc,
					   xJobDocLength );
	}
	else
	{
		/* The Jobs service sends an empty Job document when all Jobs are complete. */
		if( ( xIdKeyFound == pdFALSE ) && ( xDocKeyFound == pdFALSE ) )
		{
			configPRINTF( (
							  "\r\n"
							  "/*-----------------------------------------------------------*/\r\n"
							  "\r\n"
							  "All available Jobs complete.\r\n"
							  "\r\n"
							  "/*-----------------------------------------------------------*/\r\n"
							  "\r\n" ) );
		}
		else
		{
			configPRINTF( ( "Received an invalid Job document: %.*s\r\n",
							xRawDocumentLength,
							pcRawDocument ) );
		}
	}
}
/*-----------------------------------------------------------*/
