def single_scenario(scenario_id):
    """Return page for single scenario."""
    api = get_autostorage_api()
    scenario_manager = ScenarioManager(api)
    single_scenario_manager = scenario_manager.get_scenario(scenario_id)
    with api.get_session() as session:
        view_states = single_scenario_manager.get_view_states().with_session(session).all()

    current_view_state = view_states[0]
    current_name = current_view_state.name
    current_description = current_view_state.description

    name_form = EditScenarioNameForm(original_name=current_name)
    description_form = EditScenarioDescriptionForm(original_description=current_description)

    if name_form.rename.data and name_form.validate_on_submit():
        single_scenario_manager.rename(name_form.name.data)

        flash('Your changes have been saved.')
        return redirect(url_for('single_scenario', scenario_id=scenario_id))
    else:
        name_form.name.data = current_name

    if description_form.change_description.data and description_form.validate_on_submit():
        single_scenario_manager.change_description(description_form.description.data)

        flash('Your changes have been saved.')
        return redirect(url_for('single_scenario', scenario_id=scenario_id))
    else:
        description_form.description.data = current_description

    structure_tree = _create_tree(single_scenario_manager)

    node_manager = ScenarioNodeManager(api)
    with api.get_session() as session:
        node_states = node_manager.get_scenario_node_states().with_session(session).all()

    return render_template(
        "single_scenario.html",
        scenario_id=scenario_id,
        scenario_name=current_name,
        scenario_description=current_description,
        view_states=view_states,
        name_form=name_form,
        description_form=description_form,
        structure_tree=structure_tree,
        node_states=node_states
        )
def scenario_nodes():
    """Return page with scenario nodes."""
    new_node_form = CreateScenarioNodeForm()
    api = get_autostorage_api()
    node_manager = ScenarioNodeManager(api)
    if new_node_form.validate_on_submit():
        node_manager.create_scenario_node(new_node_form.name.data)

    with api.get_session() as session:
        node_states = node_manager.get_scenario_node_states().with_session(session).all()

    return render_template(
        "scenario_nodes.html",
        node_states=node_states,
        new_node_form=new_node_form,
        )
def _create_tree(single_scenario_manager):
    # pylint: disable=too-many-locals
    """Create view tree."""
    api = get_autostorage_api()

    structure_query = single_scenario_manager.get_current_structure_states().subquery()

    node_manager = ScenarioNodeManager(api)
    nodes_query = node_manager.get_scenario_node_states().subquery()

    joined = structure_query.join(
        nodes_query,
        structure_query.columns.node_id == nodes_query.columns.node_id
        )

    with api.get_session() as session:
        tree_nodes_data = session.query(
            select(
                columns=[
                    structure_query.columns.tree_path,
                    nodes_query.columns.name,
                    nodes_query.columns.node_id
                    ],
                from_obj=joined
                )
            ).all()

    tree = {}
    for tree_path, name, node_id in tree_nodes_data:
        path = tree_path.split('-')
        parent_key = path[0]
        subtree = tree.setdefault(parent_key, {})
        for key in path[1:]:
            parent_key = parent_key + '-' + key
            subtree = subtree.setdefault("children", {}).setdefault(parent_key, {})

        subtree['name'] = name
        subtree['node_id'] = node_id

    return tree