#!/usr/bin/python2.4
# This file is part of the Falcon repository manager
# Copyright (C) 2005-2008 Dennis Kaarsemaker
# See the file named COPYING in the root of the source tree for license details
#
# falcon-build-queue - Build queue automation

import gettext
from gettext import gettext as _
gettext.bindtextdomain('falcon','/usr/share/locale')
gettext.textdomain('falcon')

import falcon
import sys, os, optparse, shutil
import apt_pkg

usage = _("""%prog [options]""")
parser = optparse.OptionParser(usage=usage)
parser.error = lambda string: falcon.util.error(string)
parser.add_option('-r','--root', dest="rootdir",
                  help=_("Specify the rootdir"), metavar=_("DIR"))
parser.add_option('-v','--verbose', action="store_true", dest="verbose", default=False,
                  help=_("Give verbose output"))
parser.add_option('-V', '--version', action="store_true", dest="dump_version", default=False,
                  help=_("Show version and exit"))
parser.add_option('-i', '--install', action="store_true", dest="install_built", default=False,
                  help=_("Install fully built packages into the archive"))
parser.add_option('-c', '--check', action="store_true", dest="check_only", default=False,
                  help=_("Only check pending builds"))

options, args = parser.parse_args()
options.application = 'falcon-build-queue'

if options.dump_version:
    print falcon.conf.falcon_version
    sys.exit(0)
falcon.conf.set_options(options)

print _("Falcon repository manager %s (C)2005-2008 %s") % (falcon.conf.falcon_version, falcon.conf.falcon_author)
if os.getuid() == 0:
    error(_("Falcon should not be run as root"))
res = falcon.plugin.run_plugins('pre_action', 'build-queue', args)
if not res:
    error(_("Unable to proceed"))

# Run pending builds
for qi in falcon.build.QueueItem.objects.all():
    qi.run(False)

if falcon.conf.check_only:
    sys.exit(0)

incoming = os.path.join(falcon.conf.rootdir, '.falcon', 'incoming')

allfiles = os.listdir(incoming)
for changes in allfiles[:]:
    if not changes.endswith('.changes'):
        continue
    # Use dsc parsing, works fine
    control, controlfields, files = falcon.package.parse_dsc(os.path.join(incoming, changes))
    dscfile = None
    # Check existence/size/md5sum
    for f in files:
        if f.name in allfiles:
            allfiles.remove(f.name)
    try:
        for f in files:
            name = os.path.join(incoming, f.name)
            if name.endswith('.dsc'):
                dscfile = name
            if not os.path.exists(name):
                falcon.util.warning(_("Can't build %s %s, file %s is missing") % (controlfields['Source'], controlfields['Version'], f.name))
                raise AssertionError
            if os.path.getsize(name) != f.size:
                
                falcon.util.warning(_("Can't build %s %s, file %s has wrong size %d, expected %d") %
                                    (controlfields['Source'], controlfields['Version'], f.name, os.path.getsize(name), f.size))
                raise AssertionError
            sum = apt_pkg.md5sum(open(name))
            if sum != f.sum:
                falcon.util.warning(_("Can't build %s %s, file %s has wrong checksum %s, expected %s") % 
                                    (controlfields['Source'], controlfields['Version'], f.name, sum, f.sum))
                raise AssertionError
    except AssertionError:
        continue
    # Now build
    falcon.build.build(dscfile)
    shutil.move(os.path.join(incoming, changes), os.path.join(falcon.conf.rootdir, '.falcon', 'changelogs', os.path.basename(changes)))

# Are there .changes-less packages?
for dsc in allfiles[:]:
    if not dsc.endswith('.dsc'):
        continue
    control, controlfields, files = falcon.package.parse_dsc(os.path.join(incoming, dsc))
    # Check existence/size/md5sum
    for f in files:
        if f.name in allfiles:
            allfiles.remove(f.name)
    try:
        for f in files:
            name = os.path.join(incoming, f.name)
            if not os.path.exists(name):
                falcon.util.warning(_("Can't build %s %s, file %s is missing") % (controlfields['Source'], controlfields['Version'], f.name))
                raise AssertionError
            if os.path.getsize(name) != f.size:
                falcon.util.warning(_("Can't build %s %s, file %s has wrong size %d, expected %d") % 
                                    (controlfields['Source'], controlfields['Version'], f.name, os.path.getsize(name), f.size))
                raise AssertionError
            sum = apt_pkg.md5sum(open(name))
            if sum != f.sum:
                falcon.util.warning(_("Can't build %s %s, file %s has wrong checksum %s, expected %s") % 
                                    (controlfields['Source'], controlfields['Version'], f.name, sum, f.sum))
                raise AssertionError
    except AssertionError:
        continue
    # Now build
    falcon.build.build(os.path.join(incoming,dsc))

# Any files left?
if allfiles:
    falcon.util.output(_("The following files in incoming don't belong to a package:"))
    falcon.util.output(', '.join(allfiles))

falcon.plugin.run_plugins('post_action', 'build-queue', args)
