#!/usr/bin/env python
# Configure script for abakus.  I think it's better than the sample that came
# with bksys.  Feel free to do with it what you want.
# By Michael Pyne <michael.pyne@kdemail.net>

import sys
import re

BOLD="\033[1m"
RED="\033[91m"
GREEN="\033[92m"
YELLOW="\033[93m"
CYAN="\033[96m"
NORMAL="\033[0m"

PROGRAM_NAME='abakus'

# First let's see if they asked for help.
if '--help' in sys.argv:
    print '''This is a configure script to prepare %s for building.

You can pass the command line argument debug=1 to enable debugging for the
application, which can be useful if you have problems.

Otherwise, just run ./configure, and if you don't already have scons, a mini
version will be installed suitable for building %s.
'''.replace('%s', PROGRAM_NAME)
    sys.exit(0)

# Check that we have the minimum version of Python needs to run SCons.
if sys.hexversion < 0x02030000:
    # Use regexp for compatibility with ancient Python
    version = re.split(' ', sys.version)[0]

    print RED + 'Sorry, your version of Python is too old.' + NORMAL
    print PROGRAM_NAME + ' requires Python 2.3 or greater to build.'
    print "\nYou have Python " + version
    sys.exit(1)

import os

# Check if scons is installed.  We can use cool Python features now that we
# know we aren't using an ancient version of Python.
result = os.system('scons -v > /dev/null 2>&1')
scons = 'scons'

if os.WEXITSTATUS(result) == 0:
    print GREEN + "scons already installed." + NORMAL
else:
    # If we didn't find scons, don't whine to the user about it, just fix it.
    print YELLOW + 'scons not installed, installing local copy.' + NORMAL

    # Split this into two steps since some tars don't use j to mean bzip2
    # compressed.
    result = os.system('bzcat bksys/scons-mini.tar.bz2 | tar x')

    if os.WEXITSTATUS(result) != 0:
	print RED + 'Unable to extract scons' + NORMAL
	sys.exit(2)

    scons = '%s/scons' % os.getcwd()

# Now we now where scons is.  Let's create a Makefile (after we configure) so
# that all the user has to do is type 'make'.  Allow the user to pass command
# line arguments, which will be passed to the configure process.
if len(sys.argv) < 2:
    options = ''
else:
    options = " ".join(sys.argv[1:])
    # reduce is pretty cool
#    options = reduce(lambda x, y: x + '\n' + y, sys.argv[1:])

result = os.system(scons + ' configure ' + options)
if os.WEXITSTATUS(result) != 0:
    print RED + 'Unable to configure scons' + NORMAL
    sys.exit(3)

# Recursive generates a makefile for a directory.  If topDir is True, the
# Makefile is slightly different.
def generate_makefile(dir, topDir = False):

    file = name + "/Makefile"

    # Write out Makefile.
    try:
        makefile = open(file, 'w')
    except IOError:
        print RED + "Unable to open " + file + NORMAL
        sys.exit(4)

    text = '''
## Makefile automatically generated by configure

SCONS=$scons

# $scons            : compile
# $scons -c         : clean
# $scons install    : install
# $scons -c install : uninstall and clean

# Default target: use scons to build the program
all:
	@$(SCONS) -Q

# Debugging possibilies:
# $scons --debug=explain, $scons --debug=tree

# To optimize the runtime:
# $scons --max-drift=1 --implicit-deps-unchanged
debug:
	@$(SCONS) -Q --debug=tree

clean:
	@$(SCONS) -c

install:
	@$(SCONS) install

uninstall:
	@$(SCONS) uninstall

# This target creates a tarball of the project (in theory)
dist:
	@$(SCONS) dist
'''

    if topDir:
        text = text.replace('$scons', scons)
    else:
        text = text.replace('$scons', scons + ' -u')

    try:
        print "Generating " + GREEN + file + NORMAL
        makefile.write(text)
        makefile.close()
    except IOError:
        print RED + "Unable to write to the Makefile!" + NORMAL
        sys.exit(5)

# Recursively generate Makefiles for convienience.
for name, dirs, files in os.walk('.'):
    # Don't try to build hidden directories.
    remove = filter(lambda x: x[0] == '.', dirs)
    for i in remove:
        dirs.remove(i)

    if 'SConstruct' in files:
        # We're in the very top directory.
        generate_makefile(name, topDir = True)

        for dir in ['cache', 'bksys']:
            if dir in dirs:
                dirs.remove(dir)
    elif 'SConscript' in files:
        generate_makefile(name)

# The Makefile has been written, we're pretty much done.
message = '''
The Makefile(s) have been generated.  Type:
	`make'         to build %s, and
	`make install' to install %s.
'''.replace('%s', PROGRAM_NAME)

print GREEN + message + NORMAL