#!/usr/bin/python -u

import multiprocessing
import os
import platform
import shutil
import stat
import subprocess
import sys

# Disable buffering.
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

if len(sys.argv) == 1:
	kWork = os.path.join('deps', sys.platform)
elif len(sys.argv) == 2:
	kWork = sys.argv[1]

if not os.path.isdir(kWork):
	os.makedirs(kWork)
os.chdir(kWork)

kUvRepository = 'https://github.com/libuv/libuv.git'
kUvBranch = 'v1.11.0'
kUvWork = 'uv'

kV8Repository = 'https://github.com/v8/v8.git'
kV8Branch = 'branch-heads/6.0'
kV8Work = 'v8'

kLmdbRepository = 'https://github.com/LMDB/lmdb.git'
kLmdbBranch = 'LMDB_0.9.19'
kLmdbWork = 'lmdb'

cores = multiprocessing.cpu_count()
if platform.machine() == 'armv7l':
	cores = 1
print 'Using', cores, 'cores.'

def run(*args, **kw):
	print 'Running:', args
	subprocess.check_call(*args, **kw)

def makeWritableAndRetry(function, path, exc_info):
	if not os.access(path, os.W_OK):
		os.chmod(path, stat.S_IWUSR)
		function(path)
	else:
		raise

def updateUv():
	print 'libuv'
	print
	clean = False

	if os.path.exists(os.path.join(kUvWork, '.update-deps-branch')):
		haveBranch = open(os.path.join(kUvWork, '.update-deps-branch'), 'r').read().strip()
		if kUvBranch != haveBranch:
			print haveBranch, '=>', kUvBranch
			clean = True
	else:
		clean = True

	if clean:
		if os.path.isdir(os.path.join(kUvWork)):
			print 'Cleaning', kUvWork
			shutil.rmtree(os.path.join(kUvWork), onerror=makeWritableAndRetry)
	if not os.path.isdir(kUvWork):
		run(['git', 'clone', '--branch', kUvBranch, kUvRepository, kUvWork])
	open(os.path.join(kUvWork, '.update-deps-branch'), 'w').write(kUvBranch)
	if sys.platform in ('darwin', 'win32'):
		if not os.path.isdir(os.path.join(kUvWork, 'build', 'gyp')):
			run(['git', 'clone', 'https://chromium.googlesource.com/external/gyp.git', 'build/gyp'], cwd=kUvWork)

	if sys.platform == 'linux2':
		run(['./gyp_uv.py', '-f', 'make'], cwd=kUvWork)
		run(['make', '-j' + str(cores), '-C', 'out'], cwd=kUvWork)
	elif sys.platform == 'darwin':
		run(['./gyp_uv.py', '-f', 'xcode'], cwd=kUvWork)
		run(['xcodebuild', '-ARCHS="x86_64"', '-project', 'uv.xcodeproj', '-configuration', 'Release', '-target', 'All'], cwd=kUvWork)
	elif sys.platform == 'win32':
		env = os.environ.copy()
		env['VCINSTALLDIR'] = ''
		env['WINDOWSSDKDIR'] = ''
		run(['cmd', '/C', 'call', 'vcbuild.bat', 'release', 'x64'], cwd=kUvWork, env=env)

def updateLmdb():
	print 'liblmdb'
	print
	clean = False

	if os.path.exists(os.path.join(kLmdbWork, '.update-deps-branch')):
		haveBranch = open(os.path.join(kLmdbWork, '.update-deps-branch'), 'r').read().strip()
		if kLmdbBranch != haveBranch:
			print haveBranch, '=>', kLmdbBranch
			clean = True
	else:
		clean = True

	if clean:
		if os.path.isdir(os.path.join(kLmdbWork)):
			print 'Cleaning', kLmdbWork
			shutil.rmtree(os.path.join(kLmdbWork), onerror=makeWritableAndRetry)
	if not os.path.isdir(kLmdbWork):
		run(['git', 'clone', '--branch', kLmdbBranch, kLmdbRepository, kLmdbWork])
	open(os.path.join(kLmdbWork, '.update-deps-branch'), 'w').write(kLmdbBranch)

def updateV8():
	print 'v8'
	print
	clean = False

	if False:
		if os.path.exists(os.path.join(kV8Work, '.update-deps-branch')):
			haveBranch = open(os.path.join(kV8Work, '.update-deps-branch'), 'r').read().strip()
			if kV8Branch != haveBranch:
				print haveBranch, '=>', kV8Branch
				clean = True
		else:
			clean = True

	if clean:
		if os.path.isdir(kV8Work):
			shutil.rmtree(kV8Work, onerror=makeWritableAndRetry)

	if True or sys.platform == 'linux2':
		# XXX Modify this one .py file which assumes things that conflict with my debian environment.
		if os.path.isfile(os.path.join(kV8Work, 'tools/swarming_client/third_party/requests/packages/urllib3/contrib/pyopenssl.py')):
			print 'resetting tools/swarming_client'
			print run(['git', 'checkout', '.'], cwd=os.path.join(kV8Work, 'tools', 'swarming_client'))

	extension = ''
	if sys.platform == 'win32':
		extension = '.bat'
	if not os.path.isdir(kV8Work):
		run(['fetch' + extension, 'v8'])

	win32Env = os.environ.copy()
	win32Env['DEPOT_TOOLS_WIN_TOOLCHAIN'] = '0'
	win32Env['GYP_MSVS_VERSION'] = '2015'
	win32Env['GYP_GENERATORS'] = 'msvs'

	open(os.path.join(kV8Work, '.update-deps-branch'), 'w').write(kV8Branch)
	run(['git', 'fetch'], cwd=kV8Work)
	run(['git', 'checkout', kV8Branch], cwd=kV8Work)

	if sys.platform == 'win32':
		run(['gclient' + extension, 'sync'], cwd=kV8Work, env=win32Env)
	else:
		run(['gclient' + extension, 'sync'], cwd=kV8Work)

	run(['gn' + extension, 'gen', 'out', "--args=is_component_build=false treat_warnings_as_errors=false"], cwd=kV8Work, env=win32Env)
	run(['ninja', '-C', 'out'], cwd=kV8Work)

if __name__ == '__main__':
	updateUv()
	updateLmdb()
	updateV8()