#!/usr/bin/env python2

# Copyright 2019 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""
Install Debian sysroots for cross compiling Open Screen.
"""

# The sysroot is needed to ensure that binaries that get built will run on
# the oldest stable version of Debian that we currently support.
# This script can be run manually but is more often run as part of gclient
# hooks. When run from hooks this script is a no-op on non-linux platforms.

# The sysroot image could be constructed from scratch based on the current state
# of the Debian archive but for consistency we use a pre-built root image (we
# don't want upstream changes to Debian to affect the build until we
# choose to pull them in). The sysroot images are stored in Chrome's common
# data storage, and the sysroots.json file should be kept in sync with Chrome's
# copy of it.

from __future__ import print_function

import hashlib
import json
import platform
import argparse
import os
import re
import shutil
import subprocess
import sys
try:
    # For Python 3.0 and later
    from urllib.request import urlopen
except ImportError:
    # Fall back to Python 2's urllib2
    from urllib2 import urlopen

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
PARENT_DIR = os.path.dirname(SCRIPT_DIR)
URL_PREFIX = 'https://storage.googleapis.com'
URL_PATH = 'openscreen-sysroots'

VALID_ARCHS = ('arm', 'arm64')
VALID_PLATFORMS = ('stretch', 'sid')


class Error(Exception):
    pass


def GetSha1(filename):
    """Generates a SHA1 hash for validating download. Done in chunks to avoid
    excess memory usage."""
    BLOCKSIZE = 1024 * 1024
    sha1 = hashlib.sha1()
    with open(filename, 'rb') as f:
        chunk = f.read(BLOCKSIZE)
        while chunk:
            sha1.update(chunk)
            chunk = f.read(BLOCKSIZE)
    return sha1.hexdigest()


def GetSysrootDict(target_platform, target_arch):
    """Gets the sysroot information for a given platform and arch from the sysroots.json
    file."""
    if target_arch not in VALID_ARCHS:
        raise Error('Unknown architecture: %s' % target_arch)

    sysroots_file = os.path.join(SCRIPT_DIR, 'sysroots.json')
    sysroots = json.load(open(sysroots_file))
    sysroot_key = '%s_%s' % (target_platform, target_arch)
    if sysroot_key not in sysroots:
        raise Error('No sysroot for: %s' % (sysroot_key))
    return sysroots[sysroot_key]


def DownloadFile(url, local_path):
    """Uses urllib to download a remote file into local_path."""
    for _ in range(3):
        try:
            response = urlopen(url)
            with open(local_path, "wb") as f:
                f.write(response.read())
            break
        except Exception:
            pass
    else:
        raise Error('Failed to download %s' % url)

def ValidateFile(local_path, expected_sum):
    """Generates the SHA1 hash of a local file to compare with an expected hashsum."""
    sha1sum = GetSha1(local_path)
    if sha1sum != expected_sum:
        raise Error('Tarball sha1sum is wrong.'
                    'Expected %s, actual: %s' % (expected_sum, sha1sum))

def InstallSysroot(target_platform, target_arch):
    """Downloads, validates, unpacks, and installs a sysroot image."""
    sysroot_dict = GetSysrootDict(target_platform, target_arch)
    tarball_filename = sysroot_dict['Tarball']
    tarball_sha1sum = sysroot_dict['Sha1Sum']

    sysroot = os.path.join(PARENT_DIR, sysroot_dict['SysrootDir'])

    url = '%s/%s/%s/%s' % (URL_PREFIX, URL_PATH, tarball_sha1sum,
                           tarball_filename)

    stamp = os.path.join(sysroot, '.stamp')
    if os.path.exists(stamp):
        with open(stamp) as s:
            if s.read() == url:
                return

    if os.path.isdir(sysroot):
        shutil.rmtree(sysroot)
    os.mkdir(sysroot)

    tarball_path = os.path.join(sysroot, tarball_filename)
    DownloadFile(url, tarball_path)
    ValidateFile(tarball_path, tarball_sha1sum)
    subprocess.check_call(['tar', 'xf', tarball_path, '-C', sysroot])
    os.remove(tarball_path)

    with open(stamp, 'w') as s:
        s.write(url)


def parse_args(args):
    """Parses the passed in arguments into an object."""
    p = argparse.ArgumentParser()
    p.add_argument(
        'arch',
        help='Sysroot architecture: %s' % ', '.join(VALID_ARCHS))
    p.add_argument(
        'platform',
        help='Sysroot platform: %s' % ', '.join(VALID_PLATFORMS))
    p.add_argument(
        '--print-hash', action="store_true",
        help='Print the hash of the sysroot for the specified arch.')

    return p.parse_args(args)


def main(args):
    if not (sys.platform.startswith('linux') or sys.platform == 'darwin'):
        print('Unsupported platform. Only Linux and Mac OS X are supported.')
        return 1

    parsed_args = parse_args(args)
    if parsed_args.print_hash:
        print(GetSysrootDict(parsed_args.platform, parsed_args.arch)['Sha1Sum'])

    InstallSysroot(parsed_args.platform, parsed_args.arch)
    return 0


if __name__ == '__main__':
    try:
        sys.exit(main(sys.argv[1:]))
    except Error as e:
        sys.stderr.write('Installing sysroot error: {}\n'.format(e))
        sys.exit(1)
