#! /usr/bin/env python

import argparse
import glob
import os
import shutil
import signal
import subprocess
import sys

def buildRelease(version, doNotClean=False):
	"""Method that builds a release of DistMaker. Upon sucessful execution, a
	tar.gz archive will be generated named: 'DistMaker-<version>.tar.gz'. Note
	that releases of DistMaker version 0.50 or later (2018May01+) will no longer
	include static JREs."""
	# Retrieve the install path
	installPath = getInstallRoot()
	installPath = os.path.dirname(installPath)

	# Determine the workPath
	workPath = os.path.join(installPath, 'release', 'DistMaker-' + version)
	destFileGZ = os.path.join(installPath, 'release', 'DistMaker-' + version + '.tar.gz')

	# Bail if the work folder for which we compose the release already exists
	if os.path.exists(workPath) == True:
		errPrintln('Aborting DistMaker release build. Release folder already exists: ' + workPath, indent=1)
		exit(-1)

	# Bail if the release already exists
	if os.path.exists(destFileGZ) == True:
		errPrintln('Aborting DistMaker release build. Release already exists. File: ' + destFileGZ, indent=1)
		exit(-1)

	# Laydown the structure, and let the user know of the version we are building
	print('Building DistMaker release ' + version + '...')
	os.mkdir(workPath)

	# Copy the libraries
	dstPath = os.path.join(workPath, 'lib')
	os.mkdir(dstPath)
	for aLib in ['glum.jar', 'guava-18.0.jar', 'distMaker.jar']:
		srcPath = os.path.join(installPath, 'lib', aLib)
		shutil.copy2(srcPath, dstPath)

	# Copy the scripts
	dstPath = os.path.join(workPath, 'script')
	os.mkdir(dstPath)
	for aScript in ['appleUtils.py', 'linuxUtils.py', 'windowsUtils.py', 'buildDist.py', 'deployAppDist.py', 'deployJreDist.py', 'jreUtils.py', 'logUtils.py', 'miscUtils.py']:
		srcPath = os.path.join(installPath, 'script', aScript)
		shutil.copy2(srcPath, dstPath)

	# Setup the template tree
	dstPath = os.path.join(workPath, 'template')
	os.makedirs(dstPath + '/apple')
	os.makedirs(dstPath + '/background')
	os.makedirs(dstPath + '/launch4j')
	for aFile in ['appLauncher.jar', '.DS_Store.template', 'apple/JavaAppLauncher', 'background/background.png', 'launch4j/launch4j-3.12-linux-x64.tgz', 'launch4j/launch4j-3.12-macosx-x86.tgz']:
		srcPath = os.path.join(installPath, 'template', aFile)
		shutil.copy2(srcPath, dstPath + '/' + aFile)

	# Form the archive
	exeCmd = ['tar', '-czf', destFileGZ, '-C', os.path.dirname(workPath), os.path.basename(workPath)]
	retCode = subprocess.call(exeCmd)
	if retCode != 0:
		print('Failed to build tar.gz file: ' + destFileGZ)
		exit(-1)

	# Remove the workPath
	if doNotClean == False:
		shutil.rmtree(workPath)

	print('DistMaker release ' + version + ' built.')


def errPrintln(message="", indent=0):
	"""Print the specified string with a trailing newline to stderr."""
	while indent > 0:
		indent -= 1
		message = '   ' + message
	sys.stderr.write(message + '\n')


def getDistMakerVersion():
	"""Method that will return the version of the distMaker.jar file that resides
	in the library path. The version of the DistMaker release is defined by the
	value associated with the disMaker.jar file. Any failures will result in the
	abrupt exit of this script."""
	# Retrieve the install path
	installPath = getInstallRoot()
	installPath = os.path.dirname(installPath)

	# Check for distMaker.jar library prerequisite
	testPath = os.path.join(installPath, 'lib', 'distMaker.jar')
	if os.path.exists(testPath) == False:
		errPrintln('Aborting DistMaker release build. The file  ' + testPath + ' does not exist.', indent=1)
		errPrintln('Please run the buildDistMakerBin.jardesc from your workspace.', indent=1)
		exit(-1)

	try:
		exeCmd = ['java', '-cp', 'lib/distMaker.jar', 'distMaker.DistApp', '--version']
		output = subprocess.check_output(exeCmd).decode('utf-8')
		version = output.split()[1]
		return version
	except:
		errPrintln('Please run the buildDistMakerBin.jardesc from your workspace.', indent=1)
		exit(-1)


def getInstallRoot():
	"""Returns the root path where the running script is installed."""
	argv = sys.argv;
	installRoot = os.path.dirname(argv[0])
# 	print('appInstallRoot: ' + appInstallRoot)
	return installRoot


def handleSignal(signal, frame):
	"""Signal handler, typically used to capture ctrl-c."""
	print('User aborted processing!')
	sys.exit(0)


if __name__ == "__main__":
	# Logic to capture Ctrl-C and bail
	signal.signal(signal.SIGINT, handleSignal)

	# Ensure we are running version 2.7 or greater
	targVer = (2, 7)
	if sys.version_info < targVer:
		print('The installed version of python is too old. Please upgrade.')
		print('   Current version: ' + '.'.join(str(i) for i in sys.version_info))
		print('   Require version: ' + '.'.join(str(i) for i in targVer))
		sys.exit(-1)

	tmpDescr = 'Utility to build a DistMaker release\n'
	parser = argparse.ArgumentParser(prefix_chars='-', description=tmpDescr, add_help=False, fromfile_prefix_chars='@')
	parser.add_argument('--help', '-h', help='Show this help message and exit.', action='help')
	parser.add_argument('--doNotClean', default=False, action='store_true', help='Do NOT remove temporary work folder created while generating release.')
	parser.add_argument('--doFullBuild', default=False, action='store_true', help='Force a full build of the main jar file. (Unsupported action)')

	# Intercept any request for a  help message and bail
	argv = sys.argv;
	if '-h' in argv or '-help' in argv or '--help' in argv:
		parser.print_help()
		exit()

	# Parse the args
	parser.formatter_class.max_help_position = 50
	args = parser.parse_args()

	# Get the version of DistMaker we are building
	version = getDistMakerVersion()
	print('DistMaker version: ' + version)

	# TODO: Finish this functionality
	if args.doFullBuild == True:
		print("Unsupported action: [--doFullBuild]. Skipping...")

	buildRelease(version, args.doNotClean)
