#!/usr/bin/python3

"""
This script tries to set ordering in which packages ought to be sent to builders.
Input: file with names of packages (without the .spec suffix). One package name per line.
Output: sorted packages on stdout.

If the script goes in a infinite loop, that means there is a cycle or other bug.
"""

import os
import re
import sys

BR_PATTERN = re.compile('BuildRequires:\s+(.*?)(\s|$)')
PACKAGE_PATTERN_WITH_N = re.compile('%package\s+-n\s+(.*)')
PACKAGE_PATTERN = re.compile('%package\s+(.*)')

DIR = os.getenv("HOME") + '/rpm/packages'

BUILD_REQUIRES = {}
PACKAGES = {}
SPECS = {}
VISITED = {}


def parse_spec(name):
    global PACKAGES, SPECS, BUILD_REQUIRES, VISITED
    res = []
    try:
        with open(os.path.join(DIR, name, name + '.spec'), 'r') as f:
            for line in f:
                br = BR_PATTERN.match(line)
                if br:
                    p = br.group(1)
                    res.append(p)
                if line.startswith('%package'):
                    pn = PACKAGE_PATTERN_WITH_N.match(line)
                    if pn:
                        package = pn.group(1)
                        PACKAGES[package] = name
                    else:
                        pn = PACKAGE_PATTERN.match(line)
                        if pn:
                            ext = pn.group(1)
                            if ext:
                                package = name + '-' + ext
                                PACKAGES[package] = name
        BUILD_REQUIRES[name] = res[:]
        PACKAGES[name] = name
        SPECS[name] = True
        VISITED[name] = False
    except:
        pass


def print_spec(spec):
    global PACKAGES, SPECS, BUILD_REQUIRES, VISITED

    if not VISITED[spec]:
        VISITED[spec] = True
        for br in BUILD_REQUIRES[spec]:
            name = PACKAGES.get(br, '')
            if name in SPECS:
                if not VISITED[name]:
                    print_spec(name)
        print(spec)


if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: %s filename" % sys.argv[0])
        sys.exit(1)
    with open(sys.argv[1], 'r') as f:
        for line in f:
            spec = line.rstrip()
            parse_spec(spec)

    for spec in SPECS:
        print_spec(spec)
