#!/usr/bin/env python
# Copyright (C) 2011 Igalia S.L.
# Copyright (C) 2012 Gustavo Noronha Silva <gns@gnome.org>
# Copyright (C) 2012 Intel Corporation
# Copyright (C) 2012, 2013 Nokia Corporation and/or its subsidiary(-ies).
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

import jhbuildutils
import os
import shlex
import subprocess
import sys

jhbuild_revision = '93d37507d0fbf550aa3e96b5d632f3772c0189f0'

def determine_platform():
    if '--gtk' in sys.argv:
        return "gtk";
    if '--wpe' in sys.argv:
        return "wpe"
    raise ValueError('No platform specified for jhbuild-wrapper.')

try:
    platform = determine_platform()
except ValueError as e:
    sys.exit(e)

dependencies_path = jhbuildutils.get_dependencies_path(platform)
installation_prefix = os.path.abspath(os.path.join(dependencies_path, 'Root'))
source_path = os.path.abspath(os.path.join(dependencies_path, 'Source'))
jhbuild_source_path = os.path.join(source_path, 'jhbuild')
jhbuild_path = os.path.join(installation_prefix, 'bin', 'jhbuild')

def jhbuild_installed():
    return os.path.exists(jhbuild_path)


def jhbuild_cloned():
    return os.path.exists(jhbuild_source_path)


def jhbuild_at_expected_revision():
    process = subprocess.Popen(['git', 'rev-list', 'HEAD^..'], cwd=jhbuild_source_path,
                               stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    output, err = process.communicate()
    if process.returncode != 0:
        raise Exception('failed to find jhbuild revision: %s' % err)

    return output.strip() == jhbuild_revision


def update_jhbuild():
    process = subprocess.Popen(['git', 'remote', 'update', 'origin'], cwd=jhbuild_source_path)
    process.wait()
    if process.returncode != 0:
        raise Exception('jhbuild remote update origin failed with return code: %i' % process.returncode)

    process = subprocess.Popen(['git', 'checkout', '%s' % jhbuild_revision],
                               cwd=jhbuild_source_path)
    process.wait()
    if process.returncode != 0:
        raise Exception('failed to checkout treeish %s: %i' % (jhbuild_revision, process.returncode))


def clone_jhbuild():
    if not os.path.exists(source_path):
        os.makedirs(source_path)
    if not os.path.exists(installation_prefix):
        os.makedirs(installation_prefix)

    # Use only 1 thread to workaround a QEMU bug - see http://webkit.org/b/143095 for details.
    process = subprocess.Popen(['git', 'clone', '--config', 'pack.threads=1', 'https://git.gnome.org/browse/jhbuild'], cwd=source_path)
    process.wait()
    if process.returncode != 0:
        raise Exception('jhbuild git clone failed with return code: %i' % process.returncode)


def install_jhbuild():
    if "GREP_OPTIONS" in os.environ:
        del os.environ['GREP_OPTIONS']
    process = subprocess.Popen(['bash', './autogen.sh', '--prefix=%s' % installation_prefix], cwd=jhbuild_source_path)
    process.wait()
    if process.returncode != 0:
        raise Exception('jhbuild configure failed with return code: %i' % process.returncode)

    # This is a hackish approach to make the subprocess.Popen call even when people set
    # MAKE to 'make -j3' instead of using the MAKEFLAGS environment variable.
    make = shlex.split(os.environ.get('MAKE', 'make'))

    process = subprocess.Popen(make + ['install'], cwd=jhbuild_source_path)
    process.wait()
    if process.returncode != 0:
        raise Exception('jhbuild configure failed with return code: %i' % process.returncode)

def ensure_jhbuild(platform):
    if not jhbuild_cloned():
        clone_jhbuild()
        update_jhbuild()
        install_jhbuild()
    elif not jhbuild_installed() \
            or not jhbuild_at_expected_revision():
        update_jhbuild()
        install_jhbuild()

# Work-around the fact that we may get called from inside the jhbuild environment
# which will cause problems if we just cleaned the jhbuild install root
if 'UNDER_JHBUILD' in os.environ and 'ACLOCAL_FLAGS' in os.environ:
    del os.environ['ACLOCAL_FLAGS']

ensure_jhbuild(platform)

os.execve(jhbuild_path, [jhbuild_path, '--exit-on-error', '--no-interact', '-f', jhbuildutils.get_config_file_for_platform(platform)] + sys.argv[2:], os.environ)
