"""
    FusionOptimizer

An optimizer that simply applies an available [`NodeFusion`](@ref) on each step. It implements [`optimize_to_fixpoint`](@ref). The fixpoint is reached when there are no more possible [`NodeFusion`](@ref)s in the graph.

See also: [`SplitOptimizer`](@ref), [`ReductionOptimizer`](@ref)
"""
struct FusionOptimizer <: AbstractOptimizer end

function optimize_step!(optimizer::FusionOptimizer, graph::DAG)
    # generate all options
    operations = get_operations(graph)
    if fixpoint_reached(optimizer, graph)
        return false
    end

    push_operation!(graph, first(operations.nodeFusions))

    return true
end

function fixpoint_reached(optimizer::FusionOptimizer, graph::DAG)
    operations = get_operations(graph)
    return isempty(operations.nodeFusions)
end

function optimize_to_fixpoint!(optimizer::FusionOptimizer, graph::DAG)
    while !fixpoint_reached(optimizer, graph)
        optimize_step!(optimizer, graph)
    end
    return nothing
end

function String(::FusionOptimizer)
    return "fusion_optimizer"
end
