#!/usr/bin/env python3
# Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

import argparse
import gradle
import os
from shutil import copyfile
import sys
import utils
import archive

JAR_TARGETS_MAP = {
    'full': [(utils.R8, 'r8'),],
    'lib': [(utils.R8LIB, 'r8'),],
}

OTHER_TARGETS = ['LICENSE']
SBOM_TARGETS = ['r8.spdx.json']
KEEPANNO_JAR = 'keepanno-annotations.jar'


def parse_arguments():
    parser = argparse.ArgumentParser(
        description='Build and copy jars to an Android tree.')
    parser.add_argument('android_root', nargs=1, help='Android checkout root.')
    parser.add_argument('--commit_hash', default=None, help='Commit hash')
    parser.add_argument('--version',
                        default=None,
                        help='The version to download')
    parser.add_argument(
        '--targets',
        required=True,
        choices=['full', 'lib'],
        help="Use 'full' to download the full, non-optimized jars (legacy" +
        " behaviour) and 'lib' for the R8-processed, optimized jars.",
    )
    parser.add_argument(
        '--maps',
        action='store_true',
        help="Download proguard maps for jars, use only with '--target lib'.",
    )
    parser.add_argument(
        '--keepanno',
        action='store_true',
        help="Download keepanno-annotations library.",
    )
    parser.add_argument(
        '--java-max-memory-size',
        '--java_max_memory_size',
        help='Use a custom max memory size for the gradle java instance, eg, 4g'
    )
    return parser.parse_args()


def copy_targets(root, target_root, srcs, dests, maps=False):
    assert len(srcs) == len(dests)
    for i in range(len(srcs)):
        src = os.path.join(root, srcs[i])
        dest = os.path.join(target_root, 'prebuilts', 'r8', dests[i])
        if os.path.exists(dest):
            print('Copying: ' + src + ' -> ' + dest)
            copyfile(src, dest)
            if maps:
                print('Copying: ' + src + '.map -> ' + dest + '.map')
                copyfile(src + '.map', dest + '.map')
        else:
            print('WARNING: Not copying ' + src + ' -> ' + dest + ', as ' +
                  dest + ' does not exist already')


def copy_jar_targets(root, target_root, jar_targets, maps):
    srcs = list(map((lambda t: t[0] + '.jar'), jar_targets))
    dests = list(map((lambda t: t[1] + '.jar'), jar_targets))
    copy_targets(root, target_root, srcs, dests, maps=maps)


def copy_other_targets(root, target_root, other_targets):
    copy_targets(root, target_root, other_targets, other_targets)


def download_hash(root, commit_hash, target, quiet=False):
    download_target(root, target, commit_hash, True, quiet=quiet)


def download_version(root, version, target):
    download_target(root, target, version, False)


def download_target(root, target, hash_or_version, is_hash, quiet=False):
    download_path = os.path.join(root, target)
    url = archive.get_upload_destination(hash_or_version, target, is_hash)
    if not quiet:
        print('Downloading: ' + url + ' -> ' + download_path)
    utils.download_file_from_cloud_storage(url,
                                           download_path,
                                           printcmd=not quiet,
                                           quiet=quiet)


def main_download(hash_value,
                  maps,
                  targets,
                  target_root,
                  version,
                  keepanno=False):
    sbom_targets = []
    if version:
        semver = utils.check_basic_semver_version(version, allowPrerelease=True)
        # Generation of SBOM started from version 8.3.13-dev.
        if semver.larger_than(utils.SemanticVersion(8, 3, 12, 'dev')):
            sbom_targets = SBOM_TARGETS

    jar_targets = JAR_TARGETS_MAP[targets]
    final_targets = list(map(
        (lambda t: t[0] + '.jar'), jar_targets)) + OTHER_TARGETS + sbom_targets
    with utils.TempDir() as root:
        for target in final_targets:
            if hash_value:
                download_hash(root, hash_value, target)
                if maps and target not in OTHER_TARGETS:
                    download_hash(root, hash_value, target + '.map')
                if keepanno:
                    download_hash(root, hash_value, KEEPANNO_JAR)
            else:
                assert version
                download_version(root, version, target)
                if maps and target not in (OTHER_TARGETS + sbom_targets):
                    download_version(root, version, target + '.map')
                if keepanno:
                    download_version(root, version, KEEPANNO_JAR)
        copy_jar_targets(root, target_root, jar_targets, maps)
        copy_other_targets(root, target_root, OTHER_TARGETS + sbom_targets)
        if keepanno:
            copy_targets(root, target_root, [KEEPANNO_JAR], [KEEPANNO_JAR])


def main_build(maps, max_memory_size, targets, target_root):
    jar_targets = JAR_TARGETS_MAP[targets]
    gradle_args = [
        utils.GRADLE_TASK_R8LIB if targets == 'lib' else utils.GRADLE_TASK_R8
    ]
    if max_memory_size:
        gradle_args.append('-Dorg.gradle.jvmargs=-Xmx' + max_memory_size)
    gradle.run_gradle(gradle_args)
    copy_jar_targets(utils.LIBS, target_root, jar_targets, maps)
    copy_other_targets(utils.GENERATED_LICENSE_DIR, target_root, OTHER_TARGETS)


def main(args):
    if args.maps and args.targets != 'lib':
        raise Exception("Use '--maps' only with '--targets lib.")
    target_root = args.android_root[0]
    if args.commit_hash is None and args.version is None:
        main_build(args.maps, args.java_max_memory_size, args.targets,
                   target_root)
    else:
        assert args.commit_hash is None or args.version is None
        main_download(args.commit_hash, args.maps, args.targets, target_root,
                      args.version, args.keepanno)


if __name__ == '__main__':
    sys.exit(main(parse_arguments()))
