#!/usr/bin/env python

# might want to use os.path.join() to create these paths

import os, sys, time, string

# globals
root = os.getcwd()
prefix_arg = "--prefix=" + root + "/install"
build_dict = None

def build_pkgconfig():
	# http://www.freedesktop.org/software/pkgconfig/
	os.chdir(root + "/build/pkgconfig")
	os.spawnl(os.P_WAIT , "./configure", "./configure", "--enable-static", "--disable-shared", prefix_arg)
	os.spawnlp(os.P_WAIT, "make", "make")
	os.spawnlp(os.P_WAIT, "make", "make", "install")

def build_libdb():
	# http://www.sleepycat.com/download/index.shtml
	os.chdir(root + "/build/db/build_unix")
	os.spawnl(os.P_WAIT , "../dist/configure", "./configure", "--enable-shared", "--disable-static", prefix_arg)
	os.spawnlp(os.P_WAIT, "make", "make")
	os.spawnlp(os.P_WAIT, "make", "make", "install")
        #file = root + "/install/lib/libdb-4.2.dylib"
        #new_install_name = "@executable_path/../lib/libdb-4.2.dylib"
        #os.spawnlp(os.P_WAIT, "install_name_tool", "install_name_tool", "-id", new_install_name, file)


def build_libogg():
	# http://www.vorbis.com/download_unix.psp
	os.chdir(root + "/build/libogg")
	os.spawnl(os.P_WAIT , "./configure", "./configure", "--enable-static", "--disable-shared", prefix_arg)
	os.spawnlp(os.P_WAIT, "make", "make")
	os.spawnlp(os.P_WAIT, "make", "make", "install")

def build_libvorbis():
	# http://www.vorbis.com/download_unix.psp
	os.chdir(root + "/build/libvorbis")
	os.spawnl(os.P_WAIT , "./configure", "./configure", "--enable-static", "--disable-shared", prefix_arg)
	os.spawnlp(os.P_WAIT, "make", "make")
	os.spawnlp(os.P_WAIT, "make", "make", "install")

def build_libtool():
	# http://www.gnu.no/software/libtool/libtool.html
	os.chdir(root + "/build/libtool")
	os.spawnl(os.P_WAIT , "./configure", "./configure", "--enable-static", "--disable-shared", prefix_arg)
	os.spawnlp(os.P_WAIT, "make", "make")
	os.spawnlp(os.P_WAIT, "make", "make", "install")

def build_libiconv():
        # http://www.gnu.org/software/libiconv/
        os.chdir(root + "/build/libiconv")
        os.spawnl(os.P_WAIT , "./configure", "./configure", "--enable-shared", "--disable-static", "--enable-relocatable", "--without-libiconv-prefix", prefix_arg)
        os.spawnlp(os.P_WAIT, "make", "make")
        os.spawnlp(os.P_WAIT, "make", "make", "install")
        file = root + "/install/lib/libiconv.2.2.0.dylib"
        new_install_name = "@executable_path/../lib/libiconv.2.dylib"
        os.spawnlp(os.P_WAIT, "install_name_tool", "install_name_tool", "-id", new_install_name, file)

def build_libxml():
	# http://
	os.chdir(root + "/build/libxml")
	os.spawnl(os.P_WAIT , "./configure", "./configure", "--enable-shared", "--disable-static", prefix_arg)
	os.spawnlp(os.P_WAIT, "make", "make")
	os.spawnlp(os.P_WAIT, "make", "make", "install")
	file = root + "/install/lib/libxml2.2.5.8.dylib"
	new_install_name = "@executable_path/../lib/libxml2.2.dylib"
	os.spawnlp(os.P_WAIT, "install_name_tool", "install_name_tool", "-id", new_install_name, file)
        old_install_name = root + "/install/lib/libiconv.2.dylib"
        new_install_name = "@executable_path/../lib/libiconv.2.dylib"
        os.spawnlp(os.P_WAIT, "install_name_tool", "install_name_tool", "-change", old_install_name, new_install_name, file)

def build_gift():
	# http://gift.sf.net
	os.chdir(root + "/build/giFT")
	os.spawnl(os.P_WAIT , "./configure", "./configure", "--enable-shared", "--disable-static", "--enable-libvorbis","--disable-imagemagick", prefix_arg)
	#file = root + "/patch.gift"	
	#os.spawnlp(os.P_WAIT , "applypatch", "applypatch", "--force", file)
	os.spawnlp(os.P_WAIT, "make", "make")
	os.spawnlp(os.P_WAIT, "make", "make", "install")
        file = root + "/install/lib/libgift.0.0.0.dylib"
        new_install_name = "@executable_path/../lib/libgift.0.dylib"
	os.spawnlp(os.P_WAIT, "install_name_tool", "install_name_tool", "-id", new_install_name, file)
	file = root + "/install/lib/libgiftproto.0.0.0.dylib"
        new_install_name = "@executable_path/../lib/libgiftproto.0.dylib"
        os.spawnlp(os.P_WAIT, "install_name_tool", "install_name_tool", "-id", new_install_name, file)
	old_install_name = root + "/install/lib/libgift.0.dylib"
        new_install_name = "@executable_path/../lib/libgift.0.dylib"
        os.spawnlp(os.P_WAIT, "install_name_tool", "install_name_tool", "-change", old_install_name, new_install_name, file)
	file = root + "/install/bin/giftd"
	old_install_name = root + "/install/lib/libgift.0.dylib"
	new_install_name = "@executable_path/../lib/libgift.0.dylib"
	os.spawnlp(os.P_WAIT, "install_name_tool", "install_name_tool", "-change", old_install_name, new_install_name, file)
	old_install_name = root + "/install/lib/libgiftproto.0.dylib"
	new_install_name = "@executable_path/../lib/libgiftproto.0.dylib"
	os.spawnlp(os.P_WAIT, "install_name_tool", "install_name_tool", "-change", old_install_name, new_install_name, file)
	old_install_name = root + "/install/lib/libdb-4.2.dylib"
        new_install_name = "@executable_path/../lib/libdb-4.2.dylib"
        os.spawnlp(os.P_WAIT, "install_name_tool", "install_name_tool", "-change", old_install_name, new_install_name, file)

def build_openft():
	# http://gift.sf.net
	os.chdir(root + "/build/OpenFT")
	os.spawnl(os.P_WAIT , "./configure", "./configure", "--enable-libdb", prefix_arg)
	os.spawnlp(os.P_WAIT, "make", "make")
	os.spawnlp(os.P_WAIT, "make", "make", "install")
	file = root + "/install/lib/giFT/libOpenFT.so"
	old_install_name = root + "/install/lib/libgift.0.dylib"
	new_install_name = "@executable_path/../lib/libgift.0.dylib"
	os.spawnlp(os.P_WAIT, "install_name_tool", "install_name_tool", "-change", old_install_name, new_install_name, file)
	old_install_name = root + "/install/lib/libgiftproto.0.dylib"
	new_install_name = "@executable_path/../lib/libgiftproto.0.dylib"
	os.spawnlp(os.P_WAIT, "install_name_tool", "install_name_tool", "-change", old_install_name, new_install_name, file)
	old_install_name = root + "/install/lib/libdb-4.2.dylib"
	new_install_name = "@executable_path/../lib/libdb-4.2.dylib"
	os.spawnlp(os.P_WAIT, "install_name_tool", "install_name_tool", "-change", old_install_name, new_install_name, file)
        file = root + "/install/lib/libdb-4.2.dylib"
        new_install_name = "@executable_path/../lib/libdb-4.2.dylib"
        os.spawnlp(os.P_WAIT, "install_name_tool", "install_name_tool", "-id", new_install_name, file)


def build_gnutella():
	# http://gift.sf.net
	os.chdir(root + "/build/Gnutella")
	os.spawnl(os.P_WAIT , "./configure", "./configure", "--with-libxml", "--disable-nls", "--without-libiconv", prefix_arg)
	os.spawnlp(os.P_WAIT, "make", "make")
	os.spawnlp(os.P_WAIT, "make", "make", "install")
	file = root + "/install/lib/giFT/libGnutella.so"
	old_install_name = root + "/install/lib/libgift.0.dylib"
	new_install_name = "@executable_path/../lib/libgift.0.dylib"
	os.spawnlp(os.P_WAIT, "install_name_tool", "install_name_tool", "-change", old_install_name, new_install_name, file)
	old_install_name = root + "/install/lib/libgiftproto.0.dylib"
	new_install_name = "@executable_path/../lib/libgiftproto.0.dylib"
	os.spawnlp(os.P_WAIT, "install_name_tool", "install_name_tool", "-change", old_install_name, new_install_name, file)
	old_install_name = root + "/install/lib/libxml2.2.dylib"
	new_install_name = "@executable_path/../lib/libxml2.2.dylib"
	os.spawnlp(os.P_WAIT, "install_name_tool", "install_name_tool", "-change", old_install_name, new_install_name, file)
        old_install_name = root + "/install/lib/libiconv.2.dylib"
        new_install_name = "@executable_path/../lib/libiconv.2.dylib"
       	os.spawnlp(os.P_WAIT, "install_name_tool", "install_name_tool", "-change", old_install_name, new_install_name, file)


def build_fasttrack():
	# http://developer.berlios.de/projects/gift-fasttrack/
	os.chdir(root + "/build/giFT-FastTrack")
	os.spawnl(os.P_WAIT , "./configure", "./configure", prefix_arg)
	os.spawnlp(os.P_WAIT, "make", "make")
	os.spawnlp(os.P_WAIT, "make", "make", "install")
	file = root + "/install/lib/giFT/libFastTrack.so"
	old_install_name = root + "/install/lib/libgift.0.dylib"
	new_install_name = "@executable_path/../lib/libgift.0.dylib"
	os.spawnlp(os.P_WAIT, "install_name_tool", "install_name_tool", "-change", old_install_name, new_install_name, file)
	old_install_name = root + "/install/lib/libgiftproto.0.dylib"
	new_install_name = "@executable_path/../lib/libgiftproto.0.dylib"
	os.spawnlp(os.P_WAIT, "install_name_tool", "install_name_tool", "-change", old_install_name, new_install_name, file)


def build_autoconf():
	# http://www.gnu.org/software/autoconf/
	os.chdir(root + "/build/autoconf")
	os.spawnl(os.P_WAIT , "./configure", "./configure", prefix_arg)
	os.spawnlp(os.P_WAIT, "make", "make")
	os.spawnlp(os.P_WAIT, "make", "make", "install")

#def build_opennap():
	# http://developer.berlios.de/projects/gift-opennap/
	# first we check to see if we need to build autoconf 2.57
	#autoconf_ver = autoconf_version()
	#if autoconf_ver[0] <= 2 and autoconf_ver[1] < 57:
	#	print "gift-build: found old version of autoconf %u.%u" % autoconf_ver
	#	build_pkgs(("autoconf",))
	#	autoconf_ver = autoconf_version()
	#	print "gift-build: installed newer autoconf %u.%u" % autoconf_ver
	#now that autoconf has been installed, we can proceed building opennap
	#os.chdir(root + "/build/giFT-OpenNap")	
	#os.spawnlp(os.P_WAIT, "./autogen.sh", "./autogen.sh", prefix_arg)
	#os.spawnlp(os.P_WAIT, "make", "make")
	#os.spawnlp(os.P_WAIT, "make", "make", "install")
	
def build_pkgs(pkgs):
	# save time
	start_time = time.time()
	for pkg in pkgs:
		print "************ gift-build ************"
		print "\nbuilding %s...\n" % (pkg,)
		print "************ gift-build ************"
		build_start_time = time.time()
		build_dict[pkg]()
		print "\nbuilding %s took %u seconds\n" % (pkg, int(time.time() - build_start_time))
	print "build took %u seconds total" % (int(time.time() - start_time),)

def autoconf_version():
	fd = os.popen("autoconf -V")
	lines = fd.readlines()
	fd.close()
	version_str = string.split(lines[0][:-1], " ")[3]
	version_list = string.split(version_str, ".")
	return (int(version_list[0]), int(version_list[1]))


def main():
	global build_dict
	
	build_order = ("pkgconfig", "libdb", "libogg", "libvorbis", "libtool", "libiconv", "gift", "openft","libxml", "gnutella", "fasttrack")
	build_dict = {"pkgconfig" : build_pkgconfig, "libdb" : build_libdb,
					"libogg" : build_libogg, "libvorbis" : build_libvorbis, "libiconv" : build_libiconv,
					"libtool" : build_libtool, "gift" : build_gift,
					"openft" : build_openft, "libxml" : build_libxml, "gnutella" : build_gnutella,
					"fasttrack" : build_fasttrack,
					"autoconf": build_autoconf}
	
	# first setup the environment
	os.environ['PATH'] = root + "/install/bin:" + os.environ['PATH']
	os.environ['CPPFLAGS'] = "-I" + root + "/install/include"
	os.environ['LDFLAGS'] = "-L" + root + "/install/lib -headerpad_max_install_names"
	os.environ['MACOSX_DEPLOYMENT_TARGET'] = "10.2"
	os.environ['ACLOCAL_FLAGS'] = "-I " + root + "/install/share/aclocal/"

	if len(sys.argv) == 1:
		build_pkgs(build_order)
	elif len(sys.argv) == 2 and sys.argv[1] == "help":
		print build_order	
	elif len(sys.argv) == 2 and sys.argv[1] == "clean":
		# clean pkgconfig
		os.chdir(root + "/build/pkgconfig")
		os.spawnlp(os.P_WAIT, "make", "make", "distclean")
		# clean libdb
		os.chdir(root + "/build/db/build_unix")
		os.spawnlp(os.P_WAIT, "make", "make", "distclean")
		# clean libogg
		os.chdir(root + "/build/libogg")
		os.spawnlp(os.P_WAIT, "make", "make", "distclean")
		# clean libvorbis
		os.chdir(root + "/build/libvorbis")
		os.spawnlp(os.P_WAIT, "make", "make", "distclean")
		# clean libiconv
                os.chdir(root + "/build/libiconv")
                os.spawnlp(os.P_WAIT, "make", "make", "distclean")
		# clean libtool
		# NOTE: distclean is broken in libtool 1.5 because there isn't a Fortran 77 compiler
		# it tries to run make distclean inside the f77demo dir and fails
		# the solution is to manually run make distclean in all sub-directories of libtool
		# that contain a Makefile
		os.chdir(root + "/build/libtool")
		os.spawnlp(os.P_WAIT, "make", "make", "distclean")
		# clean gift
		os.chdir(root + "/build/giFT")
		os.spawnlp(os.P_WAIT, "make", "make", "distclean")
		# clean openft
		os.chdir(root + "/build/OpenFT")
		os.spawnlp(os.P_WAIT, "make", "make", "distclean")
		# clean gnutella
		os.chdir(root + "/build/Gnutella")
		os.spawnlp(os.P_WAIT, "make", "make", "distclean")
		# clean libxml
		os.chdir(root + "/build/libxml")
		os.spawnlp(os.P_WAIT, "make", "make", "distclean")
		# clean fasttrack
		os.chdir(root + "/build/giFT-FastTrack")
		os.spawnlp(os.P_WAIT, "make", "make", "distclean")
		# clean opennap
		#os.chdir(root + "/build/giFT-OpenNap")
		#os.spawnlp(os.P_WAIT, "make", "make", "distclean")
		# clean autoconf
		os.chdir(root + "/build/autoconf")
		os.spawnlp(os.P_WAIT, "make", "make", "distclean")
		
		# delete install directory
		os.spawnlp(os.P_WAIT, "sudo", "sudo", "rm", "-r", root + "/install")
		#os.rmdir(root + "/install")
	elif len(sys.argv) == 3 and sys.argv[1] == "install":
		install_root = sys.argv[2]
		# create directory structure
		if not os.path.exists(os.path.join(install_root, "bin")):
			os.makedirs(os.path.join(install_root, "bin"))
		if not os.path.exists(os.path.join(install_root, "lib", "giFT")):
			os.makedirs(os.path.join(install_root, "lib", "giFT"))
		if not os.path.exists(os.path.join(install_root, "include")):
			os.makedirs(os.path.join(install_root, "include"))
		# libgift headers
		os.spawnlp(os.P_NOWAIT, "cp", "cp", "-R", os.path.join(root,"install", "include", "libgift"), os.path.join(install_root, "include"))
		# gift daemon
		os.spawnlp(os.P_NOWAIT, "cp", "cp", os.path.join(root,"install", "bin", "giftd"), os.path.join(install_root, "bin", "giftd"))
		# plugins
		#os.spawnlp(os.P_NOWAIT, "cp", "cp", os.path.join(root, "install", "lib", "giFT", "libOpenNap.la"), os.path.join(install_root, "lib", "giFT", "libOpenNap.la"))
		#os.spawnlp(os.P_NOWAIT, "cp", "cp", os.path.join(root , "install", "lib", "giFT", "libOpenNap.so"), os.path.join(install_root, "lib", "giFT", "libOpenNap.so"))
		os.spawnlp(os.P_NOWAIT, "cp", "cp", os.path.join(root, "install", "lib", "giFT", "libFastTrack.la"), os.path.join(install_root, "lib", "giFT", "libFastTrack.la"))
		os.spawnlp(os.P_NOWAIT, "cp", "cp", os.path.join(root , "install", "lib", "giFT", "libFastTrack.so"), os.path.join(install_root, "lib", "giFT", "libFastTrack.so"))
		os.spawnlp(os.P_NOWAIT, "cp", "cp", os.path.join(root, "install", "lib", "giFT", "libGnutella.la"), os.path.join(install_root, "lib", "giFT", "libGnutella.la"))
		os.spawnlp(os.P_NOWAIT, "cp", "cp", os.path.join(root , "install", "lib", "giFT", "libGnutella.so"), os.path.join(install_root, "lib", "giFT", "libGnutella.so"))
		os.spawnlp(os.P_NOWAIT, "cp", "cp", os.path.join(root, "install", "lib", "giFT", "libOpenFT.la"), os.path.join(install_root, "lib", "giFT", "libOpenFT.la"))
		os.spawnlp(os.P_NOWAIT, "cp", "cp", os.path.join(root , "install", "lib", "giFT", "libOpenFT.so"), os.path.join(install_root, "lib", "giFT", "libOpenFT.so"))
		#files
		os.spawnlp(os.P_NOWAIT, "cp", "cp", os.path.join(root, "install", "lib", "libdb-4.2.dylib"), os.path.join(install_root, "lib", "libdb-4.2.dylib"))
		os.spawnlp(os.P_NOWAIT, "cp", "cp", os.path.join(root, "install", "lib", "libgift.0.0.0.dylib"), os.path.join(install_root, "lib", "libgift.0.dylib"))
		os.spawnlp(os.P_NOWAIT, "cp", "cp", os.path.join(root, "install", "lib", "libgiftproto.0.0.0.dylib"), os.path.join(install_root, "lib", "libgiftproto.0.dylib"))
		os.spawnlp(os.P_NOWAIT, "cp", "cp", os.path.join(root, "install", "lib", "libxml2.2.5.8.dylib"), os.path.join(install_root, "lib", "libxml2.2.dylib"))
		os.spawnlp(os.P_NOWAIT, "cp", "cp", os.path.join(root, "install", "lib", "libiconv.2.2.0.dylib"), os.path.join(install_root, "lib", "libiconv.2.dylib"))
	else:
		build_pkgs(sys.argv[1:])
	
if __name__ == "__main__":
	main()
