import itertools
import networkx as nx

def afegir_persona(g, nom, data, mare, pare):
    g.add_node(nom, naix=data)
    if mare != '':  # alternativa: if mare in g
        g.add_edge(mare, nom)
    if pare != '':  # alternativa: if pare in g
        g.add_edge(pare, nom)

def nets_1(g, nom):
    s = set()
    for fill in g.succ[nom]:
        for net in g.succ[fill]:
            s.add(net)
    return sorted(s)

def nets_2(g, nom):
    return sorted(nx.descendants_at_distance(g, nom, 2))

def nets_3(g, nom):
    succ = nx.bfs_successors(g, nom, depth_limit=2)
    fills = filter(lambda pf: pf[0] != nom, succ)
    nets_l = map(lambda pf: pf[1], fills)
    nets = itertools.chain.from_iterable(nets_l)
    return sorted(nets)

def avis_1(g, nom):
    s = set()
    for pare in g.pred[nom]:
        for avi in g.pred[pare]:
            s.add(avi)
    return sorted(s)

def avis_2(g, nom):
    grev = g.reverse()
    return sorted(nx.descendants_at_distance(grev, nom, 2))


def germans(g, nom):
    cjt = set()
    pares = list(g.pred[nom])
    if len(pares) == 2:
        p1, p2 = pares
        cjt = set(g.succ[p1]) & set(g.succ[p2])
        cjt.remove(nom)              
    return cjt

def primer_avantpassat_1(g, nom):
    pa = nom
    for x in nx.ancestors(g, nom):
        if g.nodes[x]['naix'] < g.nodes[pa]['naix']:
            pa = x
    return pa

def primer_avantpassat_2(g, nom):
    pred = nx.bfs_tree(g, nom, reverse=True)
    primer = min(pred.nodes, key=lambda n: g.nodes[n]['naix'])
    return primer

# Tria les solucions que vols provar
nets = nets_1
avis = avis_2
primer_avantpassat = primer_avantpassat_1

