#!/usr/bin/python2.4

import sys
import os
import re
import pkg_ll

def _recurse(Graph, Pkg, Field, Result = []):
    if not Pkg in Result:
        Result.append(Pkg)
        for i in Graph[Pkg][Field]:
            _recurse(Graph, i, Field, Result)
    return Result

class Packages(dict):
    def __init__(self, filename):
        self.filename = filename
        self._parse_packages()

    def _merge_rdepends(self, PkgList, rDep_Graph):
        for pkg in PkgList:
            check = [pkg] + PkgList[pkg].get('*Provides', [])
            rdeps = []
            for i in check:
                if i in rDep_Graph:
                    rdeps.extend(rDep_Graph[i])
            PkgList[pkg]['*rDepends'] = rdeps

    def _parse_packages(self):
        rDep_Graph = {}
        PkgList = {}

        for record in pkg_ll.Parser(self.filename):
            if 'Source' not in record:
                record['Source'] = record['Package']
            else:
                record['Source'] = record['Source'].split(' ',1)[0]

            pkg = record['Package']
            PkgList[pkg] = record

            record['*Provides'] = pkg_ll.parse_depends(record.get('Provides', ''))
            record['*Depends'] = pkg_ll.parse_depends(record.get('Depends', ''))

            for dep in record['*Depends']:
                if dep in rDep_Graph: rDep_Graph[dep].append(pkg)
                else: rDep_Graph[dep] = [pkg]

        self._merge_rdepends(PkgList, rDep_Graph)
        self.update(PkgList)

    def full_rdepends(self, Package):
        return _recurse(self, Package, '*rDepends')

class Sources(dict):
    def __init__(self, filename):
        self.filename = filename
        self._parse_sources()
    
    def _parse_sources(self):
        SrcList = {}
        for record in pkg_ll.Parser(self.filename):
            src = record['Package']
            record['*Binary'] = pkg_ll.parse_depends(record.get('Binary', ''))

            SrcList[src] = record

        self.update(SrcList)

class Suite:
    def __init__(self, PkgFile, SrcFile):
        if not isinstance(PkgFile, Packages):
            PkgFile = Packages(PkgFile)
        if not isinstance(SrcFile, Sources):
            SrcFile = Sources(SrcFile)

        self.Packages = PkgFile
        self.Sources = SrcFile

    def find_fucked_deps(self, lib, dev, recurse=False):
        rDepends = self.Packages[lib]['*rDepends']
        rDepends = [(self.Packages[i]['Source'],i) for i in rDepends]

        if not recurse:
            return [(src,pkg) for src,pkg in rDepends 
                    if not dev in self.Sources[src]['Build-Depends']]
        else:
            fucked = []
            to_check = [dev] + self.Packages.full_rdepends(dev)

            for src,pkg in rDepends:
                is_fucked = True
                for i in to_check:
                    if i in self.Sources[src]['Build-Depends']:
                        is_fucked = False
                        break
                if is_fucked:
                    fucked.append((src,pkg))

            return fucked

def _invert_src(res):
    result = {}
    for suite, sources in res.items():
        for pkg, record in sources.items():
            if pkg in result:
                result[pkg][suite] = record
            else:
                result[pkg] = {suite: record}

    return result

def find_src(SrcFiles, sources):
    res = {}
    for suite, filename in SrcFiles.items():
        Srcs = Sources(filename)

        res2 = {}
        for src in sources:
            if src in Srcs:
                res2[src] = Srcs[src]

        res[suite] = res2
        
    return _invert_src(res)

def installed_list():
    inst_pkg = os.popen('dpkg --get-selections').read()
    inst_pkg = inst_pkg.split('\n')

    re_inst = re.compile(r'\s+install$')
    inst_pkg = [i for i in inst_pkg if re_inst.search(i)]
    inst_pkg = [re_inst.sub('', i) for i in inst_pkg]
    inst_pkg = [(i, None) for i in inst_pkg]

    return dict(inst_pkg)

def dictify(lst):
    res = {}
    for i,j in lst:
        if i in res:
            res[i].append(j)
        else:
            res[i] = [j]
    return res

def main():
    if len(sys.argv) != 2:
        print >> sys.stderr, "Usage: %s <Packages-File>"
        sys.exit(1)

    l = Packages(sys.argv[1])

if __name__ == '__main__':
    main()
