{
    "Comment": "Finalize Bulk Session Step Function",
    "StartAt": "SetupContext",
    "States": {
        "SetupContext": {
            "Type": "Pass",
            "Parameters": {
                "bulk_session_id.$": "$[0].bulk_session_id",
                "bulk_session_ingestion_id.$": "$[0].bulk_session_ingestion_id",
                "identity_uuid.$": "$[0].identity_uuid",
                "execution_arn.$": "$[0].execution_arn",
                "assets_required.$": "$[0].assets_required",
                "submit_products.$": "$[0].submit_products",
                "send_notifications.$": "$[0].send_notifications",
                "ingestion_status.$": "$[0].ingestion_status",
                "correlation_id.$": "$[0].correlation_id",
                "bucket.$": "$[0].bucket",
                "key.$": "$[0].key"
            },
            "Next": "PrepareBulkMetadata"
        },
        "PrepareBulkMetadata": {
            "Type": "Task",
            "Resource": "${prepare_metadata_lambda_arn}",
            "Retry": [
                {
                    "ErrorEquals": [
                        "NetworkException",
                        "ReadTimeout",
                        "States.Timeout",
                        "Lambda.ServiceException",
                        "Lambda.AWSLambdaException",
                        "Lambda.SdkClientException",
                        "Lambda.TooManyRequestsException"
                    ],
                    "BackoffRate": 2,
                    "IntervalSeconds": 60,
                    "MaxAttempts": 8,
                    "Comment": "Retry 8 times with a backoff rate of 2"
                },
                {
                    "ErrorEquals": [
                        "IngestionException"
                    ],
                    "MaxAttempts": 0,
                    "Comment": "Don't retry"
                },
                {
                    "ErrorEquals": [
                        "States.ALL"
                    ],
                    "BackoffRate": 1,
                    "IntervalSeconds": 300,
                    "MaxAttempts": 1,
                    "Comment": "Retry once on any failure"
                }
            ],
            "Catch": [
                {
                    "ErrorEquals": [
                        "States.ALL"
                    ],
                    "Next": "NotifyIngestFailure",
                    "ResultPath": "$.exception",
                    "Comment": "Error after retry"
                }
            ],
            "Next": "ProcessBulkProducts"
        },
        "ProcessBulkProducts": {
            "Type": "Map",
            "Label": "Map",
            "ResultPath": null,
            "Next": "UpdateBulkSession",
            "MaxConcurrency": 25,
            "ToleratedFailurePercentage": 100,
            "ItemReader": {
                "ReaderConfig": {
                    "InputType": "JSON"
                },
                "Resource": "arn:aws:states:::s3:getObject",
                "Parameters": {
                    "Bucket.$": "$.bucket",
                    "Key.$": "$.key"
                }
            },
            "ItemSelector": {
                "bulk_session_id.$": "$.bulk_session_id",
                "bulk_session_ingestion_id.$": "$.bulk_session_ingestion_id",
                "identity_uuid.$": "$.identity_uuid",
                "execution_arn.$": "$.execution_arn",
                "assets_required.$": "$.assets_required",
                "submit_products.$": "$.submit_products",
                "send_notifications.$": "$.send_notifications",
                "ingestion_status.$": "$.ingestion_status",
                "correlation_id.$": "$.correlation_id",
                "product_info.$": "$$.Map.Item.Value.product_info"
            },
            "ItemProcessor": {
                "ProcessorConfig": {
                    "Mode": "DISTRIBUTED",
                    "ExecutionType": "STANDARD"
                },
                "StartAt": "SetNFD",
                "States": {
                    "SetNFD": {
                        "Type": "Task",
                        "Resource": "${set_nfd_lambda_arn}",
                        "Retry": [
                            {
                                "ErrorEquals": [
                                    "NetworkException",
                                    "ReadTimeout",
                                    "States.Timeout",
                                    "Lambda.ServiceException",
                                    "Lambda.AWSLambdaException",
                                    "Lambda.SdkClientException",
                                    "Lambda.TooManyRequestsException"
                                ],
                                "BackoffRate": 2,
                                "IntervalSeconds": 60,
                                "MaxAttempts": 3,
                                "Comment": "Retry 3 times with a backoff rate of 2"
                            },
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "BackoffRate": 1,
                                "IntervalSeconds": 300,
                                "MaxAttempts": 1,
                                "Comment": "Retry once on any failure"
                            }
                        ],
                        "Catch": [
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "Next": "ProductFailureState",
                                "ResultPath": "$.exception",
                                "Comment": "Error after retry"
                            }
                        ],
                        "Next": "CheckSubmitProducts"
                    },
                    "CheckSubmitProducts": {
                        "Type": "Choice",
                        "Choices": [
                            {
                                "Variable": "$.submit_products",
                                "BooleanEquals": true,
                                "Next": "SubmitProduct"
                            }
                        ],
                        "Default": "ProductSuccessState"
                    },
                    "SubmitProduct": {
                        "Type": "Task",
                        "Resource": "${submit_product_lambda_arn}",
                        "Retry": [
                            {
                                "ErrorEquals": [
                                    "RetrySubmitException",
                                    "NetworkException",
                                    "ReadTimeout",
                                    "States.Timeout",
                                    "Lambda.ServiceException",
                                    "Lambda.AWSLambdaException",
                                    "Lambda.SdkClientException",
                                    "Lambda.TooManyRequestsException"
                                ],
                                "BackoffRate": 2,
                                "IntervalSeconds": 60,
                                "MaxAttempts": 3,
                                "Comment": "Retry 3 times with a backoff rate of 2"
                            },
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "BackoffRate": 1,
                                "IntervalSeconds": 300,
                                "MaxAttempts": 1,
                                "Comment": "Retry once on any failure"
                            }
                        ],
                        "Catch": [
                            {
                                "ErrorEquals": [
                                    "RetrySubmitException"
                                ],
                                "Next": "ProductSuccessState",
                                "ResultPath": "$.exception",
                                "Comment": "Ran out of attempts to retry to submit the product"
                            },
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "Next": "ProductFailureState",
                                "ResultPath": "$.exception",
                                "Comment": "Error after retry"
                            }
                        ],
                        "Next": "ProductSuccessState"
                    },
                    "ProductSuccessState": {
                        "Type": "Succeed"
                    },
                    "ProductFailureState": {
                        "Type": "Fail"
                    }
                }
            }
        },
        "UpdateBulkSession": {
            "Type": "Task",
            "Resource": "${update_session_lambda_arn}",
            "Retry": [
                {
                    "ErrorEquals": [
                        "NetworkException",
                        "ReadTimeout",
                        "States.Timeout",
                        "Lambda.ServiceException",
                        "Lambda.AWSLambdaException",
                        "Lambda.SdkClientException",
                        "Lambda.TooManyRequestsException"
                    ],
                    "BackoffRate": 2,
                    "IntervalSeconds": 60,
                    "MaxAttempts": 8,
                    "Comment": "Retry 8 times with a backoff rate of 2"
                },
                {
                    "ErrorEquals": [
                        "IngestionException"
                    ],
                    "MaxAttempts": 0,
                    "Comment": "Don't retry"
                },
                {
                    "ErrorEquals": [
                        "States.ALL"
                    ],
                    "BackoffRate": 1,
                    "IntervalSeconds": 300,
                    "MaxAttempts": 1,
                    "Comment": "Retry once on any failure"
                }
            ],
            "Catch": [
                {
                    "ErrorEquals": [
                        "States.ALL"
                    ],
                    "Next": "NotifyIngestFailure",
                    "ResultPath": "$.exception",
                    "Comment": "Error after retry"
                }
            ],
            "Next": "CheckIngestionStatus"
        },
        "CheckIngestionStatus": {
            "Type": "Choice",
            "Choices": [
                {
                    "Variable": "$.ingestion_status",
                    "StringEquals": "failure",
                    "Next": "NotifyIngestFailure"
                }
            ],
            "Default": "NotifyIngestSuccess"
        },
        "NotifyIngestSuccess": {
            "Type": "Task",
            "Resource": "${notify_ingest_success_lambda_arn}",
            "Retry": [
                {
                    "ErrorEquals": [
                        "NetworkException",
                        "ReadTimeout",
                        "States.Timeout",
                        "Lambda.ServiceException",
                        "Lambda.AWSLambdaException",
                        "Lambda.SdkClientException",
                        "Lambda.TooManyRequestsException"
                    ],
                    "BackoffRate": 2,
                    "IntervalSeconds": 60,
                    "MaxAttempts": 8,
                    "Comment": "Retry 8 times with a backoff rate of 2"
                },
                {
                    "ErrorEquals": [
                        "States.ALL"
                    ],
                    "BackoffRate": 1,
                    "IntervalSeconds": 300,
                    "MaxAttempts": 1,
                    "Comment": "Retry once on any failure"
                }
            ],
            "Catch": [
                {
                    "ErrorEquals": [
                        "States.ALL"
                    ],
                    "Next": "FailureState",
                    "ResultPath": "$.exception",
                    "Comment": "Error after retry"
                }
            ],
            "Next": "SuccessState"
        },
        "NotifyIngestFailure": {
            "Type": "Task",
            "Resource": "${notify_ingest_failure_lambda_arn}",
            "Retry": [
                {
                    "ErrorEquals": [
                        "NetworkException",
                        "ReadTimeout",
                        "States.Timeout",
                        "Lambda.ServiceException",
                        "Lambda.AWSLambdaException",
                        "Lambda.SdkClientException",
                        "Lambda.TooManyRequestsException"
                    ],
                    "BackoffRate": 2,
                    "IntervalSeconds": 60,
                    "MaxAttempts": 8,
                    "Comment": "Retry 8 times with a backoff rate of 2"
                },
                {
                    "ErrorEquals": [
                        "States.ALL"
                    ],
                    "BackoffRate": 1,
                    "IntervalSeconds": 300,
                    "MaxAttempts": 1,
                    "Comment": "Retry once on any failure"
                }
            ],
            "Catch": [
                {
                    "ErrorEquals": [
                        "States.ALL"
                    ],
                    "Next": "FailureState",
                    "ResultPath": "$.exception",
                    "Comment": "Error after retry"
                }
            ],
            "Next": "FailureState"
        },
        "FailureState": {
            "Type": "Fail",
            "ErrorPath": "$.exception.Error",
            "CausePath": "States.Format('Error: {}, Cause: {}', $.exception.Error, $.exception.Cause)"
        },
        "SuccessState": {
            "Type": "Succeed",
            "Comment": "Bulk session ingestion completed successfully"
        }
    }
}
