#!/usr/bin/python2.2

import sys
import os
import os.path
import rpm
import string

# set up rpm dependency whiteouts
import whiteout

# FIXME: we really want this information somewhere, but not in the pkgorder
# file itself.
from rhpl.log import log
from anaconda_log import anaconda_log
anaconda_log.open("/dev/null")
log.handler = anaconda_log


rpmFD = None

import comps

def cmpHeaderByName(h1, h2):
    n1 = string.lower(h1['name'])
    n2 = string.lower(h2['name'])

    if n1 < n2:
	return -1
    elif n1 == n2:
	return 0;

    return 1

# returns 1 if comp is in the parent chain for subcomp
def isParent(comp, subcomp):
    if not subcomp:
        return 0
    if subcomp.parent == comp:
        return 1
    return isParent(comp, comp.parent)

# turns on a whole comp chain
def selectComp(comp):
    comp.select()
    if comp.parent:
        selectComp(comp.parent)

# set PKGORDER_DEBUG to get rpm debugging
if os.environ.has_key("PKGORDER_DEBUG"):
    rpm.setVerbosity(rpm.RPMLOG_DEBUG)

if len(sys.argv) != 3:
    print "pkgorder <toppath> <arch>"
    sys.exit(1)

arch = sys.argv[2]
distDir = os.path.normpath(sys.argv[1])

if not os.path.isdir(distDir):
    print "error: %s is not a directory" % distDir
    sys.exit(1)

disc1Dir = distDir + "-disc1"
disc1SrcDir = distDir + "-srpms"
disc2Dir = distDir + "-disc2"

# pull in the hdlist
f = distDir + "/RedHat/base/hdlist"
try:
    hdlist = comps.HeaderListFromFile(f, noscore = 1)
    hdlist.mergeFullHeaders(distDir + "/RedHat/base/hdlist2")    
except rpm.error:
    print "Failed to read header list", f
    sys.exit(1)
# and read the comps file
comps = comps.ComponentSet("file://%s/RedHat/base/comps.xml" %(distDir,),
                           hdlist, arch = arch, matchAllLang = 0)

# work out the order we'd like to install everything in
pkgOrder = []
pkgHash = {}

# We always want all the kernels-.* in our package list, except for a few
for package in hdlist.keys():
    if (package.startswith("kernel") and
        not package.startswith("kernel-doc") and
        not package.startswith("kernel-source") and
        not package.startswith("kernel-debug")):
        hdlist[package].selected = 1
        pkgOrder.append(hdlist[package].h)
        pkgHash[hdlist[package].h] = None

# Tier 1 language packages get priority.
tier1langs = ("en:en_US:de:de_DE:es:es_ES:fr:fr_FR:it:it_IT:ja:ja_JP:"
              "ko:ko_KR:zh:zh_CN:zh_TW:pt:pt_BR:en_GB:en_CA")

# Form a dictionary of _all_ the components, even sub comps
compsDict = {}
subComps = {}
for h in hdlist.keys():
    hdlist[h].selected = 0
    for comp in hdlist[h].comps:
        compsDict[comp.name] = comp

# make a list of all the names of all the components.
allComps = compsDict.values()

# go through all our toplevel components and add children to it.
for comp in comps:
    compsDict[comp.name] = comp
    subComps[comp] = []
    for c in allComps:
        if isParent(comp, c):
            subComps[comp].append(c)
#print subComps
#print compsDict

# FIXME: this is a hack to get things we want to be first on the CDs earlier
# in a more perfect world, we'd read the installclasses to do this
complist = ["Core", "Base", "Text-based Internet", "Web Server",
            "Windows File Server", "Printing Support",
            "Dialup Networking Support", "Server Configuration Tools",
            "Administration Tools"]
# now let's pull in all of workstation common
if comps.has_key("Workstation Common"):
    comp = comps["Workstation Common"]
    complist.append("Workstation Common")
    for name in comp.includes:
        if name not in complist:
            complist.append(name)
# a couple more that make sense to have early
complist.extend(["GNOME Desktop Environment", "Emacs", "Development Tools",
                 "Development Libraries", "X Software Development",
                 "GNOME Software Development", "KDE Desktop Environment",
                 "KDE Software Development"])
        
latelangs = []
for name in comps:
    if comp.name in complist:
        continue
    if ((comp.lang is not None) and
        (string.find(tier1langs, comp.lang) == -1)):
        latelangs.append(comp.name)
    else:
        complist.append(comp.name)
complist.extend(latelangs)

# for each comp, staring with base, list the packages
# in alphabetical order.
for name in complist:
    if not comps.has_key(name):
        continue
    comp = comps[name]
    list = []

    # don't update the hdlist selection state yet, we're going to do
    # a lot of toggling here.
    comps.freeze()
    # make sure all the components are off
    for n in compsDict.values():
        n.unselect ()

    # turn on this component, and anything that this component needs
    # to have on in order to be on.
    selectComp(comp)
    if comp.conditionalKey:
    	selectComp(comps[comp.conditionalKey])

    # Do the same for each subcomponent
    for c in subComps[comp]:
        selectComp(c)
        if c.conditionalKey:
            selectComp(compsDict[c.conditionalKey])
    # update the hdlist selection states
    comps.thaw()

    # append what got turned on to our order.

    for p in hdlist.selected():
        list.append(p.h)
    list.sort(cmpHeaderByName)
    for item in list:
        if not pkgHash.has_key (item):
            pkgOrder.append(item)
            pkgHash[item] = None

# add all of the packages that haven't been added yet.
list = []
for p in hdlist.packages.values():
    if not pkgHash.has_key (p.h):
        list.append(p.h)
list.sort(cmpHeaderByName)
for item in list:
    pkgOrder.append(item)

# Now set up rpm to run the transaction deporder
testpath = '/tmp/pkgorder-' + str (os.getpid ())
os.system ("mkdir -p " + testpath + "/var/lib/rpm")

ts = rpm.TransactionSet(testpath)
ts.setVSFlags(~(rpm.RPMVSF_NORSA|rpm.RPMVSF_NODSA))
ts.setFlags(rpm.RPMTRANS_FLAG_NOMD5|rpm.RPMTRANS_FLAG_ANACONDA)
for h in pkgOrder:
    #print "in:", h[1000000]
    ts.addInstall(h, h, 'i')
pkgOrder = []

# we have to run ts.check() before ts.order() now to set up the
# alIndex.  
ts.check()
ts.order()

# Get the order back out...
try:
    pkgOrder = ts.getKeys()
except AttributeError:
    print "you don't have the latest RPM!"
    sys.exit(1)

# print the results.
for p in pkgOrder:
    print "%s-%s-%s" % (p['name'], p['version'], p['release'])

