# Path: awscfncli2/cli/utils/common.py
# def is_not_rate_limited_exception(e):
#     return not is_rate_limited_exception(e)
# 
# def is_rate_limited_exception(e):
#     if isinstance(e, (botocore.exceptions.ClientError, botocore.exceptions.WaiterError)):
#         return 'Rate exceeded' in str(e)
#     else:
#         return False
# 
# Path: awscfncli2/cli/utils/pprint.py
# def echo_pair(key, value=None, indent=0,
#               value_style=None, key_style=None,
#               sep=': '):
#     """Pretty print a key value pair
#     :param key: The key
#     :param value: The value
#     :param indent: Number of leading spaces
#     :param value_style: click.style parameters of value as a dict, default is none
#     :param key_style:  click.style parameters of value as a dict, default is bold text
#     :param sep: separator between key and value
#     """
#     assert key
#     key = ' ' * indent + key + sep
#     if key_style is None:
#         click.secho(key, bold=False, nl=False)
#     else:
#         click.secho(key, nl=False, **key_style)
# 
#     if value is None:
#         click.echo('')
#     else:
# 
#         if value_style is None:
#             click.echo(value)
#         else:
#             click.secho(value, **value_style)
# 
# Path: awscfncli2/runner/commands/command.py
# class Command(object):
#     SKIP_UPDATE_REFERENCES = False
# 
#     def __init__(self, pretty_printer, options):
#         assert isinstance(pretty_printer, StackPrettyPrinter)
#         self.ppt = pretty_printer
#         self.options = options
# 
#     def run(self, stack_context):
#         raise NotImplementedError
# 
# Path: awscfncli2/runner/commands/utils.py
# def update_termination_protection(session,
#                                   termination_protection,
#                                   stack_name,
#                                   ppt):
#     """Update termination protection on a stack"""
# 
#     if termination_protection is None:
#         # don't care, don't change
#         return
# 
#     client = session.client('cloudformation')
# 
#     if termination_protection:
#         ppt.secho('Enabling TerminationProtection')
#     else:
#         ppt.secho('Disabling TerminationProtection', fg='red')
# 
#     client.update_termination_protection(
#         StackName=stack_name,
#         EnableTerminationProtection=termination_protection)


import uuid
import backoff
import botocore.exceptions
from collections import namedtuple
from awscfncli2.cli.utils.common import is_not_rate_limited_exception, is_rate_limited_exception
from awscfncli2.cli.utils.pprint import echo_pair
from .command import Command
from .utils import update_termination_protection

        # get changeset type: CREATE or UPDATE
        changeset_type, is_new_stack = self.check_changeset_type(client,
                                                                 parameters)

        # prepare stack parameters
        parameters['ChangeSetName'] = changeset_name
        parameters['ChangeSetType'] = changeset_type
        parameters.pop('StackPolicyBody', None)
        parameters.pop('StackPolicyURL', None)
        termination_protection = parameters.pop(
            'EnableTerminationProtection', None)

        self.ppt.pprint_parameters(parameters)

        # create changeset
        echo_pair('ChangeSet Name', changeset_name)
        echo_pair('ChangeSet Type', changeset_type)

        result = self.create_change_set(client, parameters)
        changeset_id = result['Id']
        echo_pair('ChangeSet ARN', changeset_id)

        self.ppt.wait_until_changset_complete(client, changeset_id)

        result = self.describe_change_set(client, changeset_name, parameters)
        self.ppt.pprint_changeset(result)

        # termination protection should be set after the creation of stack
        # or changeset

# Path: awscfncli2/cli/utils/common.py
# def is_not_rate_limited_exception(e):
#     return not is_rate_limited_exception(e)
# 
# def is_rate_limited_exception(e):
#     if isinstance(e, (botocore.exceptions.ClientError, botocore.exceptions.WaiterError)):
#         return 'Rate exceeded' in str(e)
#     else:
#         return False
# 
# Path: awscfncli2/cli/utils/pprint.py
# def echo_pair(key, value=None, indent=0,
#               value_style=None, key_style=None,
#               sep=': '):
#     """Pretty print a key value pair
#     :param key: The key
#     :param value: The value
#     :param indent: Number of leading spaces
#     :param value_style: click.style parameters of value as a dict, default is none
#     :param key_style:  click.style parameters of value as a dict, default is bold text
#     :param sep: separator between key and value
#     """
#     assert key
#     key = ' ' * indent + key + sep
#     if key_style is None:
#         click.secho(key, bold=False, nl=False)
#     else:
#         click.secho(key, nl=False, **key_style)
# 
#     if value is None:
#         click.echo('')
#     else:
# 
#         if value_style is None:
#             click.echo(value)
#         else:
#             click.secho(value, **value_style)
# 
# Path: awscfncli2/runner/commands/command.py
# class Command(object):
#     SKIP_UPDATE_REFERENCES = False
# 
#     def __init__(self, pretty_printer, options):
#         assert isinstance(pretty_printer, StackPrettyPrinter)
#         self.ppt = pretty_printer
#         self.options = options
# 
#     def run(self, stack_context):
#         raise NotImplementedError
# 
# Path: awscfncli2/runner/commands/utils.py
# def update_termination_protection(session,
#                                   termination_protection,
#                                   stack_name,
#                                   ppt):
#     """Update termination protection on a stack"""
# 
#     if termination_protection is None:
#         # don't care, don't change
#         return
# 
#     client = session.client('cloudformation')
# 
#     if termination_protection:
#         ppt.secho('Enabling TerminationProtection')
#     else:
#         ppt.secho('Disabling TerminationProtection', fg='red')
# 
#     client.update_termination_protection(
#         StackName=stack_name,
#         EnableTerminationProtection=termination_protection)


# Path: awscfncli2/runner/commands/stack_sync_command.py
import uuid
import backoff
import botocore.exceptions
from collections import namedtuple
from awscfncli2.cli.utils.common import is_not_rate_limited_exception, is_rate_limited_exception
from awscfncli2.cli.utils.pprint import echo_pair
from .command import Command
from .utils import update_termination_protection


        # get changeset type: CREATE or UPDATE
        changeset_type, is_new_stack = self.check_changeset_type(client,
                                                                 parameters)

        # prepare stack parameters
        parameters['ChangeSetName'] = changeset_name
        parameters['ChangeSetType'] = changeset_type
        parameters.pop('StackPolicyBody', None)
        parameters.pop('StackPolicyURL', None)
        termination_protection = parameters.pop(
            'EnableTerminationProtection', None)

        self.ppt.pprint_parameters(parameters)

        # create changeset
        echo_pair('ChangeSet Name', changeset_name)
        echo_pair('ChangeSet Type', changeset_type)

        result = self.create_change_set(client, parameters)
        changeset_id = result['Id']
        echo_pair('ChangeSet ARN', changeset_id)

        self.ppt.wait_until_changset_complete(client, changeset_id)

        result = self.describe_change_set(client, changeset_name, parameters)
        self.ppt.pprint_changeset(result)

        # termination protection should be set after the creation of stack
        # or changeset

        update_termination_protection(session,