#!/usr/bin/env python

import argparse
import distutils.spawn
import os
import shutil
import stat
import subprocess
import multiprocessing
import json

project_root = os.path.dirname(os.path.abspath(__file__))
os.chdir(project_root)

needy = os.path.join(project_root, 'needy', 'scripts', 'needy')


def bootstrap_b2():
    subprocess.check_call([needy, 'satisfy', 'boost-build'])

    b2 = os.path.join(project_root, 'b2')
    b2_bin = os.path.join(subprocess.check_output([needy, 'builddir', 'boost-build']).decode(), 'bin')

    with open(b2, 'w') as f:
        f.write('#!/bin/sh\n{} "$@"'.format(os.path.join(b2_bin, 'b2')))
    os.chmod(b2, os.stat(b2).st_mode | stat.S_IEXEC)

    bootstrap_dir = os.path.join(project_root, 'bootstrap')
    try:
        os.mkdir(bootstrap_dir)
    except OSError:
        pass

    copy_path = os.path.join(bootstrap_dir, 'b2')
    shutil.copyfile(b2, copy_path)
    os.chmod(copy_path, os.stat(copy_path).st_mode | stat.S_IEXEC)
    os.environ['PATH'] = '{}:{}'.format(bootstrap_dir, os.environ['PATH'])


def pkg_is_present(pkg):
    env = os.environ.copy()
    env['PKG_CONFIG_LIBDIR'] = ''
    return subprocess.call(['pkg-config', pkg, '--exists'], env=env) == 0

parser = argparse.ArgumentParser(description='Builds non-user-supplied dependencies.')
parser.add_argument('--bootstrap-b2',
                    default=distutils.spawn.find_executable('b2') is None,
                    action='store_true',
                    help='bootstrap b2')
parser.add_argument('--needy-target-args',
                    default='',
                    help='arguments to select the needy target with')
parser.add_argument('--needy-satisfy-args',
                    default='',
                    help='the arguments to use with needy satisfy')
parser.add_argument('--configure',
                    action='store_true',
                    help='invoked configure as well')
parser.add_argument('--clean',
                    action='store_true',
                    help='clean prior to building')
parser.add_argument('--no-dev',
                    dest='dev',
                    action='store_false',
                    help='disable dev dependencies')
parser.add_argument('--enable-jshackle',
                    action='store_true',
                    help='build jshackle as well (required for Android)')
parser.add_argument('--enable-benchmark',
                    action='store_true',
                    help='build google benchmark as well')
parser.add_argument('-j', '--concurrency', default=multiprocessing.cpu_count(), type=int, help='build concurrency')
args = parser.parse_args()

if args.bootstrap_b2:
    bootstrap_b2()

dependencies = [
    'asio',
    'fmtlib',
    'gsl',
    'json11',
    'libsodium',
    'mnmlstc',
]

if args.dev:
    dependencies.append('googletest')
if args.enable_benchmark:
    dependencies.append('benchmark')
if args.enable_jshackle:
    dependencies.append('jshackle')

dependencies = [dep for dep in dependencies if not pkg_is_present(dep)]
if not pkg_is_present('libcurl'):
    dependencies.append('curl')

needy_common_args = filter(None, args.needy_target_args.split())
needy_satisfy_args = filter(None, ['-j', str(args.concurrency)] + args.needy_satisfy_args.split())

if args.clean:
    subprocess.check_call([needy, 'clean'] + needy_common_args + dependencies)

if dependencies:
    subprocess.check_call([needy, 'satisfy'] + needy_common_args + needy_satisfy_args + dependencies)

pkgconfig_path = subprocess.check_output([needy, 'pkg-config-path'] + needy_common_args + dependencies)

config_file = 'configure.json'
print('Writing configuration to {}'.format(config_file))
with open(config_file, 'w') as configure_json:
    configure_json.write(
        json.dumps({
            'env': {
                'PKG_CONFIG_PATH': '{}:{}'.format(pkgconfig_path, os.environ.get('PKG_CONFIG_PATH', '')),
            },
            'needy': {
                'common-args': needy_common_args,
                'satisfy-args': needy_satisfy_args,
            }
        }, sort_keys=True, indent=4, separators=(',', ': ')))

if args.configure:
    subprocess.check_call('./configure')
else:
    print('Dependencies built. To use them, run ./configure')
