from cloudify.decorators import workflow
from cloudify.workflows import ctx
from cloudify.workflows import tasks as workflow_tasks
from utils import set_state_task
from utils import operation_task
from utils import link_tasks
from utils import CustomContext
from utils import generate_native_node_workflows
from utils import _get_all_nodes
from utils import _get_all_nodes_instances
from utils import _get_all_modified_node_instances
from utils import is_host_node
from workflow import WfStartEvent
from workflow import build_pre_event


# subworkflow 'install' for host 'Compute3'
def install_host_compute3(ctx, graph, custom_context):
    custom_context.add_customized_wf_node('LinuxFileSystem1')
    custom_context.add_customized_wf_node('LinuxFileSystem1')
    custom_context.add_customized_wf_node('LinuxFileSystem1')
    custom_context.add_customized_wf_node('LinuxFileSystem1')
    custom_context.add_customized_wf_node('LinuxFileSystem1')
    custom_context.add_customized_wf_node('LinuxFileSystem1')
    custom_context.add_customized_wf_node('LinuxFileSystem1')
    set_state_task(ctx, graph, 'LinuxFileSystem1', 'started', 'LinuxFileSystem1_started', custom_context)
    set_state_task(ctx, graph, 'LinuxFileSystem1', 'starting', 'LinuxFileSystem1_starting', custom_context)
    set_state_task(ctx, graph, 'LinuxFileSystem1', 'created', 'LinuxFileSystem1_created', custom_context)
    custom_context.register_native_delegate_wf_step('Compute3', 'Compute3_install')
    set_state_task(ctx, graph, 'LinuxFileSystem1', 'configured', 'LinuxFileSystem1_configured', custom_context)
    set_state_task(ctx, graph, 'LinuxFileSystem1', 'creating', 'LinuxFileSystem1_creating', custom_context)
    set_state_task(ctx, graph, 'LinuxFileSystem1', 'configuring', 'LinuxFileSystem1_configuring', custom_context)
    set_state_task(ctx, graph, 'LinuxFileSystem1', 'initial', 'LinuxFileSystem1_initial', custom_context)
    operation_task(ctx, graph, 'LinuxFileSystem1', 'cloudify.interfaces.lifecycle.start', 'start_LinuxFileSystem1', custom_context)
    operation_task(ctx, graph, 'LinuxFileSystem1', 'cloudify.interfaces.lifecycle.configure', 'configure_LinuxFileSystem1', custom_context)
    custom_context.register_native_delegate_wf_step('Volume1', 'Volume1_install')
    generate_native_node_workflows(ctx, graph, custom_context, 'install')
    link_tasks(graph, 'start_LinuxFileSystem1', 'LinuxFileSystem1_starting', custom_context)
    link_tasks(graph, 'LinuxFileSystem1_configuring', 'LinuxFileSystem1_created', custom_context)
    link_tasks(graph, 'LinuxFileSystem1_initial', 'Compute3_install', custom_context)
    link_tasks(graph, 'LinuxFileSystem1_starting', 'LinuxFileSystem1_configured', custom_context)
    link_tasks(graph, 'LinuxFileSystem1_created', 'LinuxFileSystem1_creating', custom_context)
    link_tasks(graph, 'configure_LinuxFileSystem1', 'LinuxFileSystem1_configuring', custom_context)
    link_tasks(graph, 'LinuxFileSystem1_creating', 'LinuxFileSystem1_initial', custom_context)
    link_tasks(graph, 'LinuxFileSystem1_started', 'start_LinuxFileSystem1', custom_context)
    link_tasks(graph, 'LinuxFileSystem1_configured', 'configure_LinuxFileSystem1', custom_context)
    link_tasks(graph, 'LinuxFileSystem1_initial', 'Volume1_install', custom_context)


# subworkflow 'install' for host 'NonScaledCompute'
def install_host_nonscaledcompute(ctx, graph, custom_context):
    custom_context.register_native_delegate_wf_step('NonScaledCompute', 'NonScaledCompute_install')
    generate_native_node_workflows(ctx, graph, custom_context, 'install')


# subworkflow 'install' for host 'AnotherScaleCompute'
def install_host_anotherscalecompute(ctx, graph, custom_context):
    custom_context.register_native_delegate_wf_step('AnotherScaleCompute', 'AnotherScaleCompute_install')
    generate_native_node_workflows(ctx, graph, custom_context, 'install')


# subworkflow 'install' for host 'Compute'
def install_host_compute(ctx, graph, custom_context):
    custom_context.add_customized_wf_node('FileSystem')
    custom_context.add_customized_wf_node('FileSystem')
    custom_context.add_customized_wf_node('FileSystem')
    custom_context.add_customized_wf_node('FileSystem')
    custom_context.add_customized_wf_node('FileSystem')
    custom_context.add_customized_wf_node('FileSystem')
    custom_context.add_customized_wf_node('FileSystem')
    set_state_task(ctx, graph, 'FileSystem', 'starting', 'FileSystem_starting', custom_context)
    set_state_task(ctx, graph, 'FileSystem', 'configuring', 'FileSystem_configuring', custom_context)
    set_state_task(ctx, graph, 'FileSystem', 'created', 'FileSystem_created', custom_context)
    set_state_task(ctx, graph, 'FileSystem', 'creating', 'FileSystem_creating', custom_context)
    custom_context.register_native_delegate_wf_step('Compute', 'Compute_install')
    set_state_task(ctx, graph, 'FileSystem', 'started', 'FileSystem_started', custom_context)
    set_state_task(ctx, graph, 'FileSystem', 'initial', 'FileSystem_initial', custom_context)
    operation_task(ctx, graph, 'FileSystem', 'cloudify.interfaces.lifecycle.create', 'create_FileSystem', custom_context)
    set_state_task(ctx, graph, 'FileSystem', 'configured', 'FileSystem_configured', custom_context)
    operation_task(ctx, graph, 'FileSystem', 'cloudify.interfaces.lifecycle.configure', 'configure_FileSystem', custom_context)
    operation_task(ctx, graph, 'FileSystem', 'cloudify.interfaces.lifecycle.start', 'start_FileSystem', custom_context)
    custom_context.register_native_delegate_wf_step('BlockStorage', 'BlockStorage_install')
    custom_context.register_native_delegate_wf_step('BlockStorage2', 'BlockStorage2_install')
    generate_native_node_workflows(ctx, graph, custom_context, 'install')
    link_tasks(graph, 'start_FileSystem', 'FileSystem_starting', custom_context)
    link_tasks(graph, 'configure_FileSystem', 'FileSystem_configuring', custom_context)
    link_tasks(graph, 'FileSystem_configuring', 'FileSystem_created', custom_context)
    link_tasks(graph, 'create_FileSystem', 'FileSystem_creating', custom_context)
    link_tasks(graph, 'FileSystem_initial', 'Compute_install', custom_context)
    link_tasks(graph, 'FileSystem_creating', 'FileSystem_initial', custom_context)
    link_tasks(graph, 'FileSystem_created', 'create_FileSystem', custom_context)
    link_tasks(graph, 'FileSystem_starting', 'FileSystem_configured', custom_context)
    link_tasks(graph, 'FileSystem_configured', 'configure_FileSystem', custom_context)
    link_tasks(graph, 'FileSystem_started', 'start_FileSystem', custom_context)
    link_tasks(graph, 'FileSystem_initial', 'BlockStorage_install', custom_context)
    link_tasks(graph, 'FileSystem_initial', 'BlockStorage2_install', custom_context)


# subworkflow 'uninstall' for host 'Compute3'
def uninstall_host_compute3(ctx, graph, custom_context):
    custom_context.add_customized_wf_node('LinuxFileSystem1')
    custom_context.add_customized_wf_node('LinuxFileSystem1')
    custom_context.add_customized_wf_node('LinuxFileSystem1')
    custom_context.add_customized_wf_node('LinuxFileSystem1')
    operation_task(ctx, graph, 'LinuxFileSystem1', 'cloudify.interfaces.lifecycle.stop', 'stop_LinuxFileSystem1', custom_context)
    set_state_task(ctx, graph, 'LinuxFileSystem1', 'stopping', 'LinuxFileSystem1_stopping', custom_context)
    set_state_task(ctx, graph, 'LinuxFileSystem1', 'deleted', 'LinuxFileSystem1_deleted', custom_context)
    custom_context.register_native_delegate_wf_step('Compute3', 'Compute3_uninstall')
    set_state_task(ctx, graph, 'LinuxFileSystem1', 'deleting', 'LinuxFileSystem1_deleting', custom_context)
    set_state_task(ctx, graph, 'LinuxFileSystem1', 'stopped', 'LinuxFileSystem1_stopped', custom_context)
    custom_context.register_native_delegate_wf_step('Volume1', 'Volume1_uninstall')
    generate_native_node_workflows(ctx, graph, custom_context, 'uninstall')
    link_tasks(graph, 'LinuxFileSystem1_stopped', 'stop_LinuxFileSystem1', custom_context)
    link_tasks(graph, 'stop_LinuxFileSystem1', 'LinuxFileSystem1_stopping', custom_context)
    link_tasks(graph, 'Volume1_uninstall', 'LinuxFileSystem1_deleted', custom_context)
    link_tasks(graph, 'Compute3_uninstall', 'LinuxFileSystem1_deleted', custom_context)
    link_tasks(graph, 'LinuxFileSystem1_deleted', 'LinuxFileSystem1_deleting', custom_context)
    link_tasks(graph, 'LinuxFileSystem1_deleting', 'LinuxFileSystem1_stopped', custom_context)


# subworkflow 'uninstall' for host 'NonScaledCompute'
def uninstall_host_nonscaledcompute(ctx, graph, custom_context):
    custom_context.register_native_delegate_wf_step('NonScaledCompute', 'NonScaledCompute_uninstall')
    generate_native_node_workflows(ctx, graph, custom_context, 'uninstall')


# subworkflow 'uninstall' for host 'AnotherScaleCompute'
def uninstall_host_anotherscalecompute(ctx, graph, custom_context):
    custom_context.register_native_delegate_wf_step('AnotherScaleCompute', 'AnotherScaleCompute_uninstall')
    generate_native_node_workflows(ctx, graph, custom_context, 'uninstall')


# subworkflow 'uninstall' for host 'Compute'
def uninstall_host_compute(ctx, graph, custom_context):
    custom_context.add_customized_wf_node('FileSystem')
    custom_context.add_customized_wf_node('FileSystem')
    custom_context.add_customized_wf_node('FileSystem')
    custom_context.add_customized_wf_node('FileSystem')
    set_state_task(ctx, graph, 'FileSystem', 'deleting', 'FileSystem_deleting', custom_context)
    set_state_task(ctx, graph, 'FileSystem', 'deleted', 'FileSystem_deleted', custom_context)
    set_state_task(ctx, graph, 'FileSystem', 'stopped', 'FileSystem_stopped', custom_context)
    set_state_task(ctx, graph, 'FileSystem', 'stopping', 'FileSystem_stopping', custom_context)
    operation_task(ctx, graph, 'FileSystem', 'cloudify.interfaces.lifecycle.delete', 'delete_FileSystem', custom_context)
    operation_task(ctx, graph, 'FileSystem', 'cloudify.interfaces.lifecycle.stop', 'stop_FileSystem', custom_context)
    custom_context.register_native_delegate_wf_step('Compute', 'Compute_uninstall')
    custom_context.register_native_delegate_wf_step('BlockStorage', 'BlockStorage_uninstall')
    custom_context.register_native_delegate_wf_step('BlockStorage2', 'BlockStorage2_uninstall')
    generate_native_node_workflows(ctx, graph, custom_context, 'uninstall')
    link_tasks(graph, 'delete_FileSystem', 'FileSystem_deleting', custom_context)
    link_tasks(graph, 'BlockStorage_uninstall', 'FileSystem_deleted', custom_context)
    link_tasks(graph, 'Compute_uninstall', 'FileSystem_deleted', custom_context)
    link_tasks(graph, 'BlockStorage2_uninstall', 'FileSystem_deleted', custom_context)
    link_tasks(graph, 'FileSystem_deleting', 'FileSystem_stopped', custom_context)
    link_tasks(graph, 'stop_FileSystem', 'FileSystem_stopping', custom_context)
    link_tasks(graph, 'FileSystem_deleted', 'delete_FileSystem', custom_context)
    link_tasks(graph, 'FileSystem_stopped', 'stop_FileSystem', custom_context)


def install_host(ctx, graph, custom_context, compute):
    options = {}
    options['Compute3'] = install_host_compute3
    options['NonScaledCompute'] = install_host_nonscaledcompute
    options['AnotherScaleCompute'] = install_host_anotherscalecompute
    options['Compute'] = install_host_compute
    options[compute](ctx, graph, custom_context)


def uninstall_host(ctx, graph, custom_context, compute):
    options = {}
    options['Compute3'] = uninstall_host_compute3
    options['NonScaledCompute'] = uninstall_host_nonscaledcompute
    options['AnotherScaleCompute'] = uninstall_host_anotherscalecompute
    options['Compute'] = uninstall_host_compute
    options[compute](ctx, graph, custom_context)


@workflow
def a4c_install(**kwargs):
    graph = ctx.graph_mode()
    nodes = _get_all_nodes(ctx)
    instances = _get_all_nodes_instances(ctx)
    custom_context = CustomContext(ctx, instances, nodes)
    ctx.internal.send_workflow_event(event_type='a4c_workflow_started', message=build_pre_event(WfStartEvent('install')))
    _a4c_install(ctx, graph, custom_context)
    return graph.execute()


@workflow
def a4c_uninstall(**kwargs):
    graph = ctx.graph_mode()
    nodes = _get_all_nodes(ctx)
    instances = _get_all_nodes_instances(ctx)
    custom_context = CustomContext(ctx, instances, nodes)
    ctx.internal.send_workflow_event(event_type='a4c_workflow_started', message=build_pre_event(WfStartEvent('uninstall')))
    _a4c_uninstall(ctx, graph, custom_context)
    return graph.execute()


def _a4c_install(ctx, graph, custom_context):
    #  following code can be pasted in src/test/python/workflows/tasks.py for simulation
    custom_context.add_customized_wf_node('FileSystem')
    custom_context.add_customized_wf_node('FileSystem')
    custom_context.add_customized_wf_node('LinuxFileSystem1')
    custom_context.add_customized_wf_node('FileSystem')
    custom_context.add_customized_wf_node('FileSystem')
    custom_context.add_customized_wf_node('FileSystem')
    custom_context.add_customized_wf_node('LinuxFileSystem1')
    custom_context.add_customized_wf_node('LinuxFileSystem1')
    custom_context.add_customized_wf_node('FileSystem')
    custom_context.add_customized_wf_node('LinuxFileSystem1')
    custom_context.add_customized_wf_node('FileSystem')
    custom_context.add_customized_wf_node('LinuxFileSystem1')
    custom_context.add_customized_wf_node('LinuxFileSystem1')
    custom_context.add_customized_wf_node('LinuxFileSystem1')