#!/usr/bin/env python

## Copyright (C) 2005, 2006, 2007, 2011 Free Software Foundation
## Written by Gary Benson <gbenson@redhat.com>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## 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 General Public License for more details.

import sys
sys.path.insert(0, "@python_mod_dir_expanded@")
import aotcompile
import os

def libdir():
    cmd = "%s -p" % aotcompile.PATHS["dbtool"]
    dir = os.path.abspath(os.popen(cmd, "r").readline().rstrip())
    dir, base = os.path.split(dir)
    if base != "classmap.db":
        raise aotcompile.Error, "%s: unexpected output" % cmd
    dir, base = os.path.split(dir)
    if not base.startswith("gcj-"):
        raise aotcompile.Error, "%s: unexpected output" % cmd
    return dir

def writeSourceList(srcdir, dstpath):
    def visit(fp, dir, items):
        for item in items:
            path = os.path.join(dir, item)
            if os.path.isfile(path):
                print >>fp, path
    dstdir = os.path.dirname(dstpath)
    if not os.path.isdir(dstdir):
        os.makedirs(dstdir)
    os.path.walk(srcdir, visit, open(dstpath, "w"))

def copy(srcdir, dstdir, suffix):
    srcdir = os.path.join(srcdir, suffix.lstrip(os.sep))
    dstdir = os.path.join(dstdir, suffix.lstrip(os.sep))
    os.makedirs(os.path.dirname(dstdir))
    aotcompile.system(("/bin/cp", "-a", srcdir, dstdir))

try:
    name = os.environ.get("RPM_PACKAGE_NAME")
    if name is None:
        raise aotcompile.Error, "not for use outside rpm specfiles"
    arch = os.environ.get("RPM_ARCH")
    if arch == "noarch":
        raise aotcompile.Error, "cannot be used on noarch packages"
    srcdir = os.environ.get("RPM_BUILD_ROOT")
    if srcdir in (None, "/"):
        raise aotcompile.Error, "bad $RPM_BUILD_ROOT"
    tmpdir = os.path.join(os.getcwd(), "aot-compile-rpm")
    if os.path.exists(tmpdir):
        raise aotcompile.Error, "%s exists" % tmpdir
    dstdir = os.path.join(libdir(), "gcj", name)

    compiler = aotcompile.Compiler(srcdir, dstdir, tmpdir)
    compiler.gcjflags[0:0] = os.environ.get("RPM_OPT_FLAGS", "").split() 

    # XXX: This script should not accept options, because having
    # them it cannot be integrated into rpm.  But, gcj cannot
    # build each and every jarfile yet, so we must be able to
    # exclude until it can.
    # XXX --exclude is also used in the jonas rpm to stop
    # everything being made a subset of the mammoth client
    # jarfile. Should adjust the subset checker's bias to
    # favour many small jarfiles over one big one.
    try:
        options, exclusions = sys.argv[1:], []
        while options:
            if options.pop(0) != "--exclude":
                raise ValueError
            compiler.exclusions.append(
                os.path.join(srcdir, options.pop(0).lstrip(os.sep)))
    except:
        print >>sys.stderr, "usage: %s [--exclude PATH]..." % (
            os.path.basename(sys.argv[0]))
        sys.exit(1)

    sourcelist = os.path.join(tmpdir, "sources.list")
    writeSourceList(os.getcwd(), sourcelist)
    compiler.gcjflags.append("-fsource-filename=" + sourcelist)

    compiler.compile()
    copy(tmpdir, srcdir, dstdir)

except aotcompile.Error, e:
    print >>sys.stderr, "%s: error: %s" % (
        os.path.basename(sys.argv[0]), e)
    sys.exit(1)
