#!/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 = map(lambda t: t[0], jar_targets)
  if max_memory_size:
    gradle_args.append('-Dorg.gradle.jvmargs=-Xmx' + max_memory_size)
  gradle.RunGradle(gradle_args)
  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()))
