#!/usr/bin/env python

import sys
import os
import urllib
import glob
import subprocess

mongodb_urls = {'Linux': {'i686': 'http://fastdl.mongodb.org/linux/mongodb-linux-i686-static-1.8.2.tgz',
                          'x86_64': 'http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-static-legacy-1.8.2.tgz'},
                'Darwin': {'i386': 'http://fastdl.mongodb.org/osx/mongodb-osx-i386-1.8.2.tgz',
                           'x86_64': 'http://fastdl.mongodb.org/osx/mongodb-osx-x86_64-1.8.2.tgz'}}

node_url = 'http://nodejs.org/dist/node-v0.4.9.tar.gz'
node_srcdir = 'node-v0.4.9'

openssl_src_url = 'http://www.openssl.org/source/openssl-1.0.0d.tar.gz'
openssl_srcdir = 'openssl-1.0.0d'

lockerproject_git_url = 'git://github.com/LockerProject/Locker.git'

# Helper functions
def dlProgress(count, blockSize, totalSize):
    percent = int(count*blockSize*100/totalSize)
    sys.stdout.write("\rDownloaded %2d%%" % percent)
    sys.stdout.flush()

system      = os.uname()[0]
arch        = os.uname()[-1]

os.mkdir('lockerproject')
os.mkdir('lockerproject/bin')

# prepend the bin path to the OS path so we can make sure the local version
# of each executable is preferred
os.environ['PATH'] = ':'.join([os.getcwd() + '/lockerproject/bin', os.getenv('PATH')])


# Step 1a: fetch mongodb
mongodb_url = mongodb_urls[system][arch]

print "Fetching mongodb for " + system + " " + arch + " from " + mongodb_url

os.mkdir('mongodb')
os.chdir('mongodb')

urllib.urlretrieve(mongodb_url, 'mongodb.tgz', reporthook=dlProgress)
print " ...done."

# Step 1b: unpack mongodb
os.system('tar xf mongodb.tgz')

# Step 1c: hardlink binaries into tar staging bin directory
[os.link(binary, '../lockerproject/bin/' + os.path.basename(binary)) for binary in glob.glob('*/bin/*')]

# Step 1 donezo
os.chdir('..')


# Step 2a: fetch node.js source
print "Fetching node.js source from " + node_url

os.mkdir('nodejs')
os.chdir('nodejs')
os.mkdir('installroot')

urllib.urlretrieve(node_url, node_srcdir + '.tar.gz', reporthook=dlProgress)
print " ...done."

# Step 2b: unpack node.js
print "Unpacking node.js"
os.system('tar xvf ' + node_srcdir + '.tar.gz > ../node-manifest.log 2>&1')
os.chdir(node_srcdir)

if system != 'Darwin':
    # Step 2c: patch configured source
    print "Patching node.js source to build statically."
    os.system('patch -p2 < ../../patches/node-static-build.patch')

# Step 2d: configure source for building
print "Configuring node.js"
os.system('./configure --prefix=../installroot > ../../node-configure.log 2>&1')

# Step 2e: build
print "Building node.js"
os.system('make install > ../../node-build.log 2>&1')

# Step 2f: hardlink node binary into tar staging directory
print "Linking node.js into lockerball root."
os.chdir('../..')
os.link('nodejs/installroot/bin/node', 'lockerproject/bin/node')

# Step 2 fin


# Step 3a: fetch OpenSSL source
print "Fetching OpenSSL from " + openssl_src_url

os.mkdir('openssl')
os.chdir('openssl')

urllib.urlretrieve(openssl_src_url, openssl_srcdir + ".tar.gz", reporthook=dlProgress)
print " ...done."

# Step 3b: unpack OpenSSL
print "Unpacking OpenSSL"
os.system('tar xvf ' + openssl_srcdir + '.tar.gz > ../openssl-manifest.log 2>&1')
os.chdir(openssl_srcdir)

if system != 'Darwin':
    # Step 3c: patch the source to build the OpenSSL app to actually be static
    print "Patching OpenSSL source to build openssl binary statically."
    os.system('patch -p2 < ../../patches/openssl-app-static-build.patch')

# Step 3c: configure OpenSSL to be built statically
print "Configuring OpenSSL"
os.system('./config no-shared > ../../openssl-configure.log 2>&1')

# Step 3d: build
print "Building OpenSSL"
os.system('make > ../../openssl-build.log 2>&1')

# Step 3e: hardlink openssl binary into tar staging directory
os.link('apps/openssl', '../../lockerproject/bin/openssl')

# Step 3 complete!
os.chdir('../..')


# Step 4: check out locker project code
print "Cloning locker source from Github."

os.chdir('lockerproject')
os.system('git clone --quiet ' + lockerproject_git_url + ' code')

os.chdir('code')
git = subprocess.Popen(['git', 'rev-parse', '--short', 'HEAD'], stdout=subprocess.PIPE, shell=False)
(locker_version, err) = git.communicate()

# Step 5: run npm
print "Running npm in code directory..."

os.system('npm install > ../../npm-install.log 2>&1')

os.chdir('..')


# Step 6: set up virtualenv and install python dependencies
print "Setting up Python environment..."
os.system('virtualenv --setuptools --no-site-packages . > ../virtualenv-setup.log')
os.system('. bin/activate && python code/setupEnv.py > ../setupenv-install.log')
os.system('virtualenv --relocatable . > ../virtualenv-relocatable-config.log')


# Step 7: copy the runtime script into place
print "Copying runtime script into place."

os.link('../run', 'run')


# Step 8: include a copy of lockerbox in the tarball
print "Cloning lockerbox into lockerproject."

os.system('git clone --quiet https://github.com/smurthas/lockerbox.git')

# Step 9: build the tarball
print "Building the tarball..."

os.chdir('..')
os.system('tar cvfz lockerproject-' + locker_version.rstrip() + '-' + system + '-' + arch + '.tar.gz lockerproject > lockerball-assembly.log 2>&1')


# That should be everything!
print "Finished!"
