#!/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"]
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):
  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.GetUploadDestination(
    hash_or_version,
    target,
    is_hash)
  if not quiet:
    print('Downloading: ' + url + ' -> ' + download_path)
  utils.download_file_from_cloud_storage(url, download_path, quiet=quiet)

def main_download(hash, maps, targets, target_root, version, keepanno=False):
  jar_targets = JAR_TARGETS_MAP[targets]
  final_targets = list(map((lambda t: t[0] + '.jar'), jar_targets)) + OTHER_TARGETS
  with utils.TempDir() as root:
    for target in final_targets:
      if hash:
        download_hash(root, hash, target)
        if maps and target not in OTHER_TARGETS:
          download_hash(root, hash, target + '.map')
        if keepanno:
          download_hash(root, hash, KEEPANNO_JAR)
      else:
        assert version
        download_version(root, version, target)
        if maps and target not in OTHER_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)
    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.RunGradle(gradle_args, new_gradle=True)
  copy_jar_targets(utils.LIBS, target_root, jar_targets, maps)
  copy_other_targets(utils.GENERATED_LICENSE_DIR, target_root)

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 == None and args.version == None:
    main_build(args.maps, args.java_max_memory_size, args.targets, target_root)
  else:
    assert args.commit_hash == None or args.version == None
    main_download(
      args.commit_hash, args.maps, args.targets, target_root, args.version, args.keepanno)

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