#!/usr/bin/env python3

import sys
import networkx as nx

sys.path.append("/usr/share/botch")
from util import read_reduced_deps, read_weak_deps, read_graphml

# the feedback vertex set is a list of unversioned source packages
# TODO: make it versioned to make the source package selection unique!


def profile_build_fvs(g, fvs, weak_deps, reduced_deps, verbose=False):
    # for all source vertices in the fvs, remove their droppable build
    # dependencies
    for n, a in g.nodes(data=True):
        if a["kind"] != "SrcPkg":
            continue
        if "src:" + a["name"] not in fvs:
            continue
        todrop = set()
        for v1, v2 in g.out_edges([n]):
            n1 = "src:" + g.nodes[v1]["name"]
            n2 = g.nodes[v2]["name"]
            if n2 in weak_deps or (n1 in reduced_deps and n2 in reduced_deps[n1]):
                todrop.add((v1, v2))
        g.remove_edges_from(todrop)
    return g


if __name__ == "__main__":
    import argparse

    parser = argparse.ArgumentParser(
        description="Remove droppable dependencies from a given set of "
        + "source packages. List is given on standard input if "
        + "not supplied as the last positional argument."
    )
    parser.add_argument(
        "graph", metavar="graph.xml", type=read_graphml, help="graph in GraphML format"
    )
    parser.add_argument(
        "fvs",
        metavar="fvs.list",
        type=read_weak_deps,
        help="list of source packages to profile build (a "
        + "feedback vertex set makes the graph acyclic)",
    )
    parser.add_argument(
        "--remove-weak",
        default=set(),
        type=read_weak_deps,
        help="A filename containing a list of weak build " + "dependencies",
    )
    parser.add_argument(
        "--remove-reduced",
        metavar="./droppable/foo.list",
        type=read_reduced_deps,
        help="One or more filename containing a list of "
        + "droppable build dependencies, separated by "
        + "commas.",
    )
    parser.add_argument("--verbose", action="store_true", help="be verbose")
    args = parser.parse_args()
    ret = profile_build_fvs(
        args.graph, args.fvs, args.remove_weak, args.remove_reduced, args.verbose
    )
    nx.write_graphml(ret, getattr(sys.stdout, "buffer", sys.stdout))
