import re
import os

class Package(object):
    __slots__ = ('name', 'categories', 'requires', 'required_by')

    def __init__(self, name):
        self.name = name
        self.categories = set()
        self.requires = set()
        self.required_by = set()

class Packages(dict):
    def __getitem__(self, name):
        value = self.get(name, None)
        if value is None:
            value = Package(name)
            self[name] = value
        return value

def load_packages_graph(dirname=r'http%3a%2f%2fmirrors.kernel.org%2fsourceware%2fcygwin%2f'):
    packages = Packages()
    name = None
    for line in open(os.path.join(dirname, 'setup-2.ini')):
        line = line.strip()
        if line.startswith('#'):
            continue
        m = re.match(r'@\s*([^\s]+)', line)
        if m:
            name = m.group(1)
            continue
        assert not line.startswith('@'), line
        if name is None:
            continue
        m = re.match(r'category: (.*)$', line)
        if m:
            package = packages[name]
            categories = m.group(1).split()
            for catname in categories:
                package.categories.add(catname)
            continue
        m = re.match(r'requires: (.*)$', line)
        if m:
            package = packages[name]
            requires = m.group(1).split()
            for reqname in requires:
                package.requires.add(reqname)
                packages[reqname].required_by.add(name)
            continue
        m = re.match(r'\[.*\]', line)
        if m:
            name = None
            continue
    return packages
allpackages = load_packages_graph()

def find_installed_packages(dirname=r'C:\cygwin-1.7\etc\setup'):
    packages = set()
    for filename in os.listdir(dirname):
        if filename.endswith('.lst.gz'):
            packages.add(filename[:-7])
    return packages
installedpackages = find_installed_packages()

needpackages = set()
for name in sorted(installedpackages):
    package = allpackages[name]
    if 'Base' in package.categories:
        continue # should be installed by default
    if package.required_by.intersection(installedpackages):
        continue # should be installed by some other package
    needpackages.add(name)
print "@echo off"
print "setup-1.7.exe -P %s" % ','.join(sorted(needpackages))

