#!/usr/bin/env python3

# 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)
