# Path: cloudify_rollback_workflow/lifecycle.py
# def rollback_node_instances(graph,
#                             node_instances,
#                             related_nodes=None,
#                             name_prefix=''):
#     def __init__(self,
#                  graph,
#                  node_instances=None,
#                  related_nodes=None,
#                  modified_relationship_ids=None,
#                  ignore_failure=False,
#                  name_prefix=''):
#     def rollback(self):
#     def _process_node_instances(self,
#                                 ctx,
#                                 node_instance_subgraph_func,
#                                 graph_finisher_func):
#     def _finish_uninstall(self, graph, subgraphs):
#     def _finish_subgraphs(self, graph, subgraphs, intact_op, install):
#         def intact_on_dependency_added(instance, rel, source_task_sequence):
#     def _handle_dependency_creation(source_subgraph, target_subgraph,
#                                     operation, target_id, graph):
#     def _add_dependencies(self, graph, subgraphs, instances, install,
#                           on_dependency_added=None):
# def set_send_node_event_on_error_handler(task, instance):
# def _skip_nop_operations(task, pre=None, post=None):
# def _relationships_operations(graph,
#                               node_instance,
#                               operation,
#                               reverse=False,
#                               modified_relationship_ids=None):
# def _relationship_operations(relationship, operation):
# def is_host_node(node_instance):
# def _host_pre_stop(host_node_instance):
#     def __init__(self, instance=None, instance_id=None):
#     def dump(self):
#     def __call__(self, tsk):
# def _relationship_subgraph_on_failure(subgraph):
# def _node_get_state_handler(tsk):
# def rollback_node_instance_subgraph(instance, graph, ignore_failure):
#     def set_ignore_handlers(_subgraph):
# class UtilitiesLifecycleProcessor(object):
# class _SendNodeEventHandler(object):


from cloudify.decorators import workflow
from cloudify.workflows.tasks_graph import make_or_get_graph
from cloudify.plugins.lifecycle import uninstall_node_instances, \
    set_send_node_event_on_error_handler
from cloudify_rollback_workflow import lifecycle as utilitieslifecycle

    for instance in unresolved_node_instances:
        ctx.logger.debug("unresolved node instance:{}".format(instance.id))

    intact_nodes = set(ctx.node_instances) - set(unresolved_node_instances)

    for instance in intact_nodes:
        ctx.logger.debug("intact node instance:{}".format(instance.id))

    if full_rollback:
        # The first uninstall is because a bug in the uninstall workflow:
        # if node in `configured` state the uninstall try's to run stop so
        # until then we need rollback always to `deleted`.
        ctx.logger.debug("Start full rollback")
        uninstall_node_instances(ctx.graph_mode(),
                                 node_instances=set(unresolved_node_instances),
                                 related_nodes=intact_nodes,
                                 ignore_failure=True,
                                 name_prefix='uninstall-a'
                                 )
        # For older than 5.1 Cloudify versions.
        ctx.refresh_node_instances()
        uninstall_node_instances(
            graph=ctx.graph_mode(),
            node_instances=ctx.node_instances,
            ignore_failure=False,
            name_prefix='uninstall-b')

    # Build rollback graph and execute
    else:

# Path: cloudify_rollback_workflow/lifecycle.py
# def rollback_node_instances(graph,
#                             node_instances,
#                             related_nodes=None,
#                             name_prefix=''):
#     def __init__(self,
#                  graph,
#                  node_instances=None,
#                  related_nodes=None,
#                  modified_relationship_ids=None,
#                  ignore_failure=False,
#                  name_prefix=''):
#     def rollback(self):
#     def _process_node_instances(self,
#                                 ctx,
#                                 node_instance_subgraph_func,
#                                 graph_finisher_func):
#     def _finish_uninstall(self, graph, subgraphs):
#     def _finish_subgraphs(self, graph, subgraphs, intact_op, install):
#         def intact_on_dependency_added(instance, rel, source_task_sequence):
#     def _handle_dependency_creation(source_subgraph, target_subgraph,
#                                     operation, target_id, graph):
#     def _add_dependencies(self, graph, subgraphs, instances, install,
#                           on_dependency_added=None):
# def set_send_node_event_on_error_handler(task, instance):
# def _skip_nop_operations(task, pre=None, post=None):
# def _relationships_operations(graph,
#                               node_instance,
#                               operation,
#                               reverse=False,
#                               modified_relationship_ids=None):
# def _relationship_operations(relationship, operation):
# def is_host_node(node_instance):
# def _host_pre_stop(host_node_instance):
#     def __init__(self, instance=None, instance_id=None):
#     def dump(self):
#     def __call__(self, tsk):
# def _relationship_subgraph_on_failure(subgraph):
# def _node_get_state_handler(tsk):
# def rollback_node_instance_subgraph(instance, graph, ignore_failure):
#     def set_ignore_handlers(_subgraph):
# class UtilitiesLifecycleProcessor(object):
# class _SendNodeEventHandler(object):


# Path: cloudify_rollback_workflow/workflows.py
from cloudify.decorators import workflow
from cloudify.workflows.tasks_graph import make_or_get_graph
from cloudify.plugins.lifecycle import uninstall_node_instances, \
    set_send_node_event_on_error_handler
from cloudify_rollback_workflow import lifecycle as utilitieslifecycle


    for instance in unresolved_node_instances:
        ctx.logger.debug("unresolved node instance:{}".format(instance.id))

    intact_nodes = set(ctx.node_instances) - set(unresolved_node_instances)

    for instance in intact_nodes:
        ctx.logger.debug("intact node instance:{}".format(instance.id))

    if full_rollback:
        # The first uninstall is because a bug in the uninstall workflow:
        # if node in `configured` state the uninstall try's to run stop so
        # until then we need rollback always to `deleted`.
        ctx.logger.debug("Start full rollback")
        uninstall_node_instances(ctx.graph_mode(),
                                 node_instances=set(unresolved_node_instances),
                                 related_nodes=intact_nodes,
                                 ignore_failure=True,
                                 name_prefix='uninstall-a'
                                 )
        # For older than 5.1 Cloudify versions.
        ctx.refresh_node_instances()
        uninstall_node_instances(
            graph=ctx.graph_mode(),
            node_instances=ctx.node_instances,
            ignore_failure=False,
            name_prefix='uninstall-b')

    # Build rollback graph and execute
    else:

        utilitieslifecycle.rollback_node_instances(