using LightGraphs

"""
    get_features_instance(graph, path_matpower)

Return the dict of the instances features.
"""
function get_features_instance(graph, path_matpower)
    features = Dict("graph" => readf.getfeatures_graph(graph))
    merge!(features, Dict("OPF" => readf.getfeatures_OPF(path_matpower)))
    merge!(features, Dict("kernel" => readf.getfeatures_kernel(graph)))
    return features
end

"""
    get_features_decomposition(chordal_graph, nb_added_edges, cliques, cliquetree)

Return the dict of the decompositions features.
"""
function get_features_decomposition(chordal_graph, nb_added_edges, cliques, cliquetree)
    features = Mongoc.BSON("nb_added_edges_chordal_extension" => nb_added_edges)
    chordal_graph_features = Mongoc.BSON("chordal_graph" => readf.getfeatures_graph(chordal_graph))
    cliques_features = Mongoc.BSON("cliques" => readf.getfeatures_cliques(chordal_graph, cliques))
    kernel_graph_features = Mongoc.BSON("kernel" => readf.getfeatures_kernel(chordal_graph))
    merge!(features, chordal_graph_features, cliques_features, kernel_graph_features)
    return features
end

function recompute_chordal_graph_features(manager::ExperimentManager)
    MPI.Init()
    comm = MPI.COMM_WORLD
    rank = MPI.Comm_rank(comm)
    size = MPI.Comm_size(comm)
    instance_graphs = Dict()
    for instance in manager.instances
        instance_graphs[instance["_id"]] = construct_network_graph(instance["paths"]["matpower"])
    end
    if rank == 0
        @info "Size: $size"
        indexes = get_indexes(manager, :solve, size,
                              [true,false],
                              [true,false],
                              [true,false])
        for (i, index) in enumerate(indexes)
            @info "[$rank] Rank $(i - 1): $(index[begin]) -> $(index[end]) | $(length(index))"
            MPI.Isend(index, i - 1, 0, comm)
        end
        if length(indexes) < size
            for i in length(indexes) + 1:size
                MPI.Isend(Vector{Int}(undef,0), i - 1, 0, comm)
            end
        end
    end
    MPI.Barrier(comm)
    @info "[$rank] Retrieving the number of instances/decompositions to process"
    status = MPI.Probe(0, 0, comm)
    count = MPI.Get_count(status, Int)
    if count == 0
        @info "[$rank] Exciting because no instances/decompositions to process"
        MPI.Finalize()
        return
    end
    indexes = Array{Int}(undef, count)
    MPI.Irecv!(indexes, 0, 0, comm)
    @info "[$rank] Processing"
    decompositions = collect(manager.decompositions)
    for (i, id) in enumerate(indexes)
        d = decompositions[id]
        @info "[$rank] Processing $(d["_id"]["instance_name"]): $(d["_id"]["oid"]): $(i) / $(length(indexes))"
        graph = construct_graph_
        features = Mongoc.BSON("instance_graph" => graph_features,
                               "kernel" => kernel_features)
        db.setfeatures_decomposition!(manager.decompositions,
                                      d["_id"]["instance_name"],
                                      d["_id"]["oid"],
                                      features)
    end
    @info "[$rank] Process done."
    MPI.Finalize()
end
