#!/usr/bin/python
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Library General Public License as published by
# the Free Software Foundation; version 2 only
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# Copyright 2004, 2005 Red Hat, Inc.
#
# Author: Phil Knirsch
#

import sys, os.path

PYRPMDIR = "/usr/share/pyrpm"
if not PYRPMDIR in sys.path:
    sys.path.append(PYRPMDIR)
from pyrpm import __version__
from pyrpm import *
from pyrpm.yum import RpmYum

def usage():
    print """
    pyrpmcheckrepo [outputoptions] [options] install [dirs | regex] update [repo] [dirs | regex]

    The dirs and regex following the install command will be used to simulate
    the original installed system.
    The first option following the update command can be a repo, rest is the
    same as for install.

outputoptions
    [--files] print file names insted of NEVRA
    [--script] ommit headings, just output packages

    [--install] pkgs to be installed
    [--notinstalled] pkgs from the install that did not get installed
    [--installed] pkg list after install
    [--update] pkgs to be installed as update
    [--leftover] pkgs not updated
    [--updated] pkg list after update
    [--notupdated] pkgs from the update that did not get installed

options:
    [-?, --help] [--version]
    [--quiet] [-v, --verbose] [-y]
    [-c CONFIGFILE] [--dbpath DIRECTORY] [-r, --root DIRECTORY]
    [-h, --hash] [--force] [--oldpackage] [--justdb] [--test]
    [--ignoresize] [--ignorearch] [--exactarch]
    [--noconflicts] [--fileconflicts]
    [--nodeps] [--signature]
    [--noorder] [--noscripts] [--notriggers]
    [--autoerase] [--installpkgs="pkg1 pkg2 pkg2 ..."]
    [--enablerepo=repoid|repoglob] [--disablerepo=repoid|repoglob]

Warning: Some of the options are not evaluated yet"""


def tuples2dict(l):
    d = {}
    for k, v in l:
        d[k] = v
    return d

def addlist2dict(d, l):
    for e in l:
        d[e] = None

def diff(d1, d2, neg=False):
    if not neg:
        d = d1.copy()
        for e in d2:
            if d.has_key(e):
                del d[e]
    else:
        d = {}
        for e in d2:
            if d1.has_key(e):
                d[e] = d2[e]
    return d

def print_dict(d, message, options):
    if not options["--script"]:
        print message
    if options["--files"]:
        for nevra, p in d.iteritems():
            print p.source
    else:
        for nevra in d:
            print nevra


def print_results(options, install, installed, update, updated):
    print_files = options["--files"]

    install = tuples2dict([(p.getNEVRA(), p) for p in install])
    installed = tuples2dict([(p.getNEVRA(), p) for p in installed])
    update = tuples2dict([(p.getNEVRA(), p) for p in update])
    updated = tuples2dict([(p.getNEVRA(), p) for p in updated])

    if options["--notinstalled"]:
        print_dict(diff(install, installed), "Not installed:", options)
    if options["--install"]:
         print_dict(install, "Install:", options)
    if options["--installed"]:
        print_dict(installed, "Installed:", options)
    if options["--update"]:
        print_dict(update, "Update:", options)
    if options["--leftover"]:
        print_dict(diff(installed, updated, True), "Leftovers:", options)
    if options["--updated"]:
        print_dict(updated, "Updated:", options)
    if options["--notupdated"]:
        print_dict(diff(update, updated), "Not updated:", options)

#
# Main program
#
def main():
    # Our yum worker object
    yum = RpmYum(rpmconfig)

    # Disabled fileconflicts per default in yum
    rpmconfig.nofileconflicts = 1

    # Default is to be a little verbose.
    rpmconfig.verbose = -1
    rpmconfig.debug = -1
    rpmconfig.warning = -1

    # We always do run in test mode
    rpmconfig.test = 1

    # No default repo
    rpmconfig.yumconf = ['/etc/nosuchconf']

    # Don't do any diskchecks
    rpmconfig.ignoresize = 1

    # Do autoerase by default
    yum.setAutoerase(1)

    # Don't ask if we really want to do this
    yum.setConfirm(0)

    # Argument parsing
    output_options = {
        "--files" : 0,
        "--script" : 0,
        "--install" : 0,
        "--notinstalled" : 0,
        "--installed" : 0,
        "--update" : 0,
        "--leftover" : 0,
        "--updated" : 0,
        "--notupdated" : 0,
        }

    nr = 1
    for nr, arg in enumerate(sys.argv):
        if nr == 0: continue
        if output_options.has_key(arg):
            output_options[arg] = 1
        else:
            break

        for opt, val in output_options.iteritems():
            if opt in ["--files", "--script"]: continue
            if val: break # at least one thing to output
        else:
            # if nothing to output
            # restore old behavior
            output_options["--leftover"] = 1

    args = parseYumOptions(sys.argv[nr:], yum)
    if not args:
        usage()
        return 0

    if args[0] != "install":
        print "No install command found."
        usage()
        return 0

    for pos in xrange(len(args)):
        if args[pos] == "update":
            break
    else:
        print "No update command found."
        usage()
        return 0

    instargs = args[1:pos]
    upargs = args[pos+1:]

    if os.path.isfile(upargs[0]) and not upargs[0].endswith(".rpm"):
        rpmconfig.yumconf = [upargs[0]]
        upargs = upargs[1:]

    yum.setCommand("update")
    db = database.memorydb.RpmMemoryDB("", None)
    if yum.prepareTransaction(db) == 0:
        return 0
    if yum.runArgs(instargs) == 0:
        return 0
    if yum.runDepRes() == 0:
        return 0
    if yum.runCommand() == 0:
        return 0

    # all packages from the cmd line
    install = {}
    addlist2dict(install, yum.repos.getPkgs())

    # the packages that really got installed
    #  some arch trans compatible or broken pkgs might be missing
    installed = yum.opresolver.getDatabase().getPkgs()

    yum.repos.removeAllDBs()
    db = database.memorydb.RpmMemoryDB("", None)
    db.addPkgs(installed)
    if yum.prepareTransaction(db) == 0:
        return 0
    if yum.runArgs(upargs) == 0:
        return 0
    if yum.runDepRes() == 0:
        return 0
    if yum.runCommand() == 0:
        return 0

    update = {}
    addlist2dict(update, yum.repos.getPkgs())

    updated = yum.opresolver.getDatabase().getPkgs()

    print_results(output_options, install, installed, update, updated)

    return 1

if __name__ == '__main__':
    if not run_main(main):
        sys.exit(1)

# vim:ts=4:sw=4:showmatch:expandtab
