#!/usr/bin/python

import ri_data
import ri_func_dep
from xml.dom import minidom
import os.path

dep_xml = os.path.join(os.path.dirname(__file__), '../xml/dependency.xml')

class Depending:
    ''' Class recording depending relation '''
    dict={}
    def __init__(self, n):
        self.name = n
        self.depending = set()
        # flag for resolve recursive
        self.resolved  = False
        Depending.dict[n] = self

    def resolve_recursive(self):
        if self.resolved: return
        for d in self.depending:
            Depending.dict[d].resolve_recursive()
        tmp=set(self.depending)
        for d in self.depending:
            tmp.update(Depending.dict[d].depending)
        self.depending = tmp
        self.resolved = True

class Depended:
    ''' Class recording depended by relation '''
    dict={}
    def __init__(self, n):
        self.name = n
        self.depended_by = set()
        Depended.dict[n] = self

def construct_depending():
    xml_doc  = minidom.parse(dep_xml)
    xml_root = xml_doc.firstChild
    xml_dict = {}
    for n in xml_root.childNodes:
        if n.nodeType == n.ELEMENT_NODE and n.nodeName == 'package':
            xml_dict[n.attributes['name'].value] = n 
            Depending(n.attributes['name'].value)

    for d in Depending.dict.values():
        n = xml_dict[d.name]
        for r in n.getElementsByTagName('runtime'):
            for dep in r.getElementsByTagName('depending'):
                d.depending.add(dep.attributes['package'].value)

def resolve_recursive_depending():
    for d in Depending.dict.values():
        d.resolve_recursive()

def construct_depended():
    for d in Depending.dict.values():
        for dep in d.depending:
            if not Depended.dict.has_key(dep):
                Depended(dep)
            Depended.dict[dep].depended_by.add(d.name)

def get_extra_depending(fun_pkg_list = []):
    l = ri_data.Group.get_install_pkgs() + fun_pkg_list

    set1 = set(l)
    set2 = set(set1)

    for d in set1:
        set2.update(Depending.dict[d].depending)

    res = {}
    for d in set2.difference(set1):
        res[d] = Depended.dict[d].depended_by.intersection(set1)

    return res

class dependency_init():
    ''' init dependency package and funcation'''
    func_dep_list = []
    func_dep_dict={}
    dep_dict={}
    def __init__(self):
        dependency_init.func_dep_dict = ri_func_dep.check_function_depending()
        dependency_init.func_dep_list.extend(dependency_init.func_dep_dict.values())
        construct_depending()
        resolve_recursive_depending()
        construct_depended()
        dependency_init.dep_dict = get_extra_depending(dependency_init.func_dep_list)

