import time


def sql_runner(rdsdata, resource_arn, secret_arn):
    """
    Creates a function that runs a SQL statement on an Amazon Aurora cluster.
    Because Amazon Aurora is serverless, the first time it is called the cluster might
    not be ready and will raise a BadRequestException. The runner function catches the
    exception, waits, and retries.

    :param rdsdata: A Boto3 Amazon RDS Data Service client.
    :param resource_arn: The Amazon Resource Name (ARN) of the Amazon Aurora cluster.
    :param secret_arn: The ARN of a secret that contains credentials required to
                       access the Amazon Aurora cluster.
    :return: A function that can be called to run SQL statements in the Amazon Aurora
             cluster.
    """
    def _run(statement, database=None):
        """
        Runs SQL statements in the specified Amazon Aurora cluster.

        :param statement: The SQL statement to run.
        :param database: When specified, the statement is run on this database.
                         Otherwise, the statement is run without a database context.
        :return: The response from Amazon RDS Data Service.
        """
        kwargs = {'resourceArn': resource_arn, 'secretArn': secret_arn,
                  'sql': statement}
        if database is not None:
            kwargs['database'] = database
        response = None
        tries = 5
        while tries > 0:
            try:
                response = rdsdata.execute_statement(**kwargs)
                break
            except rdsdata.exceptions.BadRequestException:
                print("Got BadRequestException. This occurs when the Aurora "
                      "database is not ready. Waiting and trying again...")
                time.sleep(10)
                tries -= 1
        return response
    return _run