#!/usr/bin/env python3
# Copyright (c) 2019, 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.

# This script is designed to run on a buildbot to build from the source
# of https://github.com/google/desugar_jdk_libs and publish to the
# r8-release Cloud Storage Bucket.
#
# These files are uploaded:
#
#   raw/desugar_jdk_libs/<VERSION>/desugar_jdk_libs.jar
#   raw/desugar_jdk_libs/<VERSION>/desugar_jdk_libs.zip
#   raw/com/android/tools/desugar_jdk_libs/<VERSION>/desugar_jdk_libs-<VERSION>.jar
#
# The first two are the raw jar file and the maven compatible zip file. The
# third is the raw jar file placed and named so that the URL
# https://storage.googleapis.com/r8-releases/raw can be treated as a maven
# repository to fetch the artifact com.android.tools:desugar_jdk_libs:1.0.0

import archive
import defines
import git_utils
import gradle
import hashlib
import jdk
import optparse
import os
import re
import shutil
import subprocess
import sys
import utils
import zipfile

VERSION_FILE_JDK8 = 'VERSION.txt'
VERSION_FILE_JDK11_LEGACY = 'VERSION_JDK11_LEGACY.txt'
VERSION_FILE_JDK11_MINIMAL = 'VERSION_JDK11_MINIMAL.txt'
VERSION_FILE_JDK11 = 'VERSION_JDK11.txt'
VERSION_FILE_JDK11_NIO = 'VERSION_JDK11_NIO.txt'

VERSION_MAP = {
  'jdk8': VERSION_FILE_JDK8,
  'jdk11_legacy': VERSION_FILE_JDK11_LEGACY,
  'jdk11_minimal': VERSION_FILE_JDK11_MINIMAL,
  'jdk11': VERSION_FILE_JDK11,
  'jdk11_nio': VERSION_FILE_JDK11_NIO
}

GITHUB_REPRO = 'desugar_jdk_libs'

BASE_LIBRARY_NAME = 'desugar_jdk_libs'

LIBRARY_NAME_MAP = {
  'jdk8': BASE_LIBRARY_NAME,
  'jdk11_legacy': BASE_LIBRARY_NAME,
  'jdk11_minimal': BASE_LIBRARY_NAME + '_minimal',
  'jdk11': BASE_LIBRARY_NAME,
  'jdk11_nio': BASE_LIBRARY_NAME + '_nio'
}

MAVEN_RELEASE_TARGET_MAP = {
  'jdk8': 'maven_release',
  'jdk11_legacy': 'maven_release_jdk11_legacy',
  'jdk11_minimal': 'maven_release_jdk11_minimal',
  'jdk11': 'maven_release_jdk11',
  'jdk11_nio': 'maven_release_jdk11_nio'
}

MAVEN_RELEASE_ZIP = {
  'jdk8': BASE_LIBRARY_NAME + '.zip',
  'jdk11_legacy': BASE_LIBRARY_NAME + '_jdk11_legacy.zip',
  'jdk11_minimal': BASE_LIBRARY_NAME + '_jdk11_minimal.zip',
  'jdk11': BASE_LIBRARY_NAME + '_jdk11.zip',
  'jdk11_nio': BASE_LIBRARY_NAME + '_jdk11_nio.zip'
}


def ParseOptions(argv):
  result = optparse.OptionParser()
  result.add_option('--variant',
      help="Variant(s) to build",
      metavar=('<variants(s)>'),
      choices=['jdk8', 'jdk11_legacy', 'jdk11_minimal', 'jdk11', 'jdk11_nio'],
      default=[],
      action='append')
  result.add_option('--dry-run', '--dry_run',
      help='Running on bot, use third_party dependency.',
      default=False,
      action='store_true')
  result.add_option('--dry-run-output', '--dry_run_output',
      help='Output directory for dry run.',
      type="string", action="store")
  result.add_option('--github-account', '--github_account',
      help='GitHub account to clone from.',
      default="google",
      type="string", action="store")
  result.add_option('--build_only', '--build-only',
      help='Build desugared library without archiving.',
      type="string", action="store")
  (options, args) = result.parse_args(argv)
  return (options, args)


def GetVersion(version_file_name):
  with open(version_file_name, 'r') as version_file:
    lines = [line.strip() for line in version_file.readlines()]
    lines = [line for line in lines if not line.startswith('#')]
    if len(lines) != 1:
      raise Exception('Version file '
          + version_file + ' is expected to have exactly one line')
    version = lines[0].strip()
    utils.check_basic_semver_version(
        version, 'in version file ' + version_file_name, allowPrerelease = True)
    return version


def Upload(options, file_name, storage_path, destination, is_main):
  print('Uploading %s to %s' % (file_name, destination))
  if options.dry_run:
    if options.dry_run_output:
      dry_run_destination = \
          os.path.join(options.dry_run_output, os.path.basename(file_name))
      print('Dry run, not actually uploading. Copying to '
        + dry_run_destination)
      shutil.copyfile(file_name, dry_run_destination)
    else:
      print('Dry run, not actually uploading')
  else:
    utils.upload_file_to_cloud_storage(file_name, destination)
    print('File available at: %s' %
        destination.replace('gs://', 'https://storage.googleapis.com/', 1))

def CloneDesugaredLibrary(github_account, checkout_dir):
  git_utils.GitClone(
    'https://github.com/'
        + github_account + '/' + GITHUB_REPRO, checkout_dir)

def GetJavaEnv():
  java_env = dict(os.environ, JAVA_HOME = jdk.GetJdk11Home())
  java_env['PATH'] = java_env['PATH'] + os.pathsep + os.path.join(jdk.GetJdk11Home(), 'bin')
  java_env['GRADLE_OPTS'] = '-Xmx1g'
  return java_env


def BuildDesugaredLibrary(checkout_dir, variant, version = None):
  if not variant in MAVEN_RELEASE_TARGET_MAP:
    raise Exception('Variant ' + variant + ' is not supported')
  if variant != 'jdk8' and variant != 'jdk11_legacy' and version is None:
    raise Exception('Variant ' + variant + ' require version for undesugaring')
  with utils.ChangedWorkingDirectory(checkout_dir):
    bazel = os.path.join(utils.BAZEL_TOOL, 'lib', 'bazel', 'bin', 'bazel')
    cmd = [
        bazel,
        '--bazelrc=/dev/null',
        'build',
        '--spawn_strategy=local',
        '--verbose_failures',
        MAVEN_RELEASE_TARGET_MAP[variant]]
    utils.PrintCmd(cmd)
    subprocess.check_call(cmd, env=GetJavaEnv())
    cmd = [bazel, 'shutdown']
    utils.PrintCmd(cmd)
    subprocess.check_call(cmd, env=GetJavaEnv())

    # Locate the library jar and the maven zip with the jar from the
    # bazel build.
    if variant == 'jdk8':
      library_jar = os.path.join(
          checkout_dir, 'bazel-bin', 'src', 'share', 'classes', 'java', 'libjava.jar')
    else:
      # All JDK11 variants use the same library code.
      library_jar = os.path.join(
          checkout_dir, 'bazel-bin', 'jdk11', 'src', 'd8_java_base_selected_with_addon.jar')
    maven_zip = os.path.join(
      checkout_dir,
      'bazel-bin',
      MAVEN_RELEASE_ZIP[variant])

    if variant != 'jdk8' and variant != 'jdk11_legacy':
      # The undesugaring is temporary...
      undesugared_maven_zip = os.path.join(checkout_dir, 'undesugared_maven')
      Undesugar(variant, maven_zip, version, undesugared_maven_zip)
      undesugared_maven_zip = os.path.join(checkout_dir, 'undesugared_maven.zip')
      return (library_jar, undesugared_maven_zip)
    else:
      return (library_jar, maven_zip)

def hash_for(file, hash):
  with open(file, 'rb') as f:
    while True:
      # Read chunks of 1MB
      chunk = f.read(2 ** 20)
      if not chunk:
        break
      hash.update(chunk)
  return hash.hexdigest()

def write_md5_for(file):
  hexdigest = hash_for(file, hashlib.md5())
  with (open(file + '.md5', 'w')) as file:
    file.write(hexdigest)

def write_sha1_for(file):
  hexdigest = hash_for(file, hashlib.sha1())
  with (open(file + '.sha1', 'w')) as file:
    file.write(hexdigest)

def Undesugar(variant, maven_zip, version, undesugared_maven_zip):
  gradle.RunGradle(['testJar', 'repackageTestDeps'])
  with utils.TempDir() as tmp:
    with zipfile.ZipFile(maven_zip, 'r') as zip_ref:
      zip_ref.extractall(tmp)
    desugar_jdk_libs_jar = os.path.join(
          tmp,
          'com',
          'android',
          'tools',
          LIBRARY_NAME_MAP[variant],
          version,
          '%s-%s.jar' % (LIBRARY_NAME_MAP[variant], version))
    print(desugar_jdk_libs_jar)
    undesugared_jar = os.path.join(tmp, 'undesugared.jar')
    buildLibs = os.path.join(defines.REPO_ROOT, 'build', 'libs')
    cmd = [jdk.GetJavaExecutable(),
      '-cp',
      '%s:%s:%s' % (os.path.join(buildLibs, 'r8_with_deps.jar'), os.path.join(buildLibs, 'r8tests.jar'), os.path.join(buildLibs, 'test_deps_all.jar')),
      'com.android.tools.r8.desugar.desugaredlibrary.jdk11.DesugaredLibraryJDK11Undesugarer',
      desugar_jdk_libs_jar,
      undesugared_jar]
    print(cmd)
    try:
      output = subprocess.check_output(cmd, stderr = subprocess.STDOUT).decode('utf-8')
    except subprocess.CalledProcessError as e:
      print(e)
      print(e.output)
      raise e
    print(output)
    # Copy the undesugared jar into place and update the checksums.
    shutil.copyfile(undesugared_jar, desugar_jdk_libs_jar)
    write_md5_for(desugar_jdk_libs_jar)
    write_sha1_for(desugar_jdk_libs_jar)
    shutil.make_archive(undesugared_maven_zip, 'zip', tmp)
    print(undesugared_maven_zip)
    output = subprocess.check_output(['ls', '-l', os.path.dirname(undesugared_maven_zip)], stderr = subprocess.STDOUT).decode('utf-8')
    print(output)

def MustBeExistingDirectory(path):
  if (not os.path.exists(path) or not os.path.isdir(path)):
    raise Exception(path + ' does not exist or is not a directory')

def BuildAndUpload(options, variant):
  if options.build_only:
    with utils.TempDir() as checkout_dir:
      CloneDesugaredLibrary(options.github_account, checkout_dir)
      (library_jar, maven_zip) = BuildDesugaredLibrary(checkout_dir, variant)
      shutil.copyfile(
        library_jar,
        os.path.join(options.build_only, os.path.basename(library_jar)))
      shutil.copyfile(
        maven_zip,
        os.path.join(options.build_only, os.path.basename(maven_zip)))
      return

  # Only handling versioned desugar_jdk_libs.
  is_main = False

  with utils.TempDir() as checkout_dir:
    CloneDesugaredLibrary(options.github_account, checkout_dir)
    version = GetVersion(os.path.join(checkout_dir, VERSION_MAP[variant]))

    destination = archive.GetVersionDestination(
        'gs://', LIBRARY_NAME_MAP[variant] + '/' + version, is_main)
    if utils.cloud_storage_exists(destination) and not options.dry_run:
      raise Exception(
          'Target archive directory %s already exists' % destination)

    (library_jar, maven_zip) = BuildDesugaredLibrary(checkout_dir, variant, version)

    storage_path = LIBRARY_NAME_MAP[variant] + '/' + version
    # Upload the jar file with the library.
    destination = archive.GetUploadDestination(
        storage_path, LIBRARY_NAME_MAP[variant] + '.jar', is_main)
    Upload(options, library_jar, storage_path, destination, is_main)

    # Upload the maven zip file with the library.
    destination = archive.GetUploadDestination(
        storage_path, MAVEN_RELEASE_ZIP[variant], is_main)
    Upload(options, maven_zip, storage_path, destination, is_main)

    # Upload the jar file for accessing GCS as a maven repro.
    maven_destination = archive.GetUploadDestination(
        utils.get_maven_path('desugar_jdk_libs', version),
        'desugar_jdk_libs-%s.jar' % version,
        is_main)
    if options.dry_run:
      print('Dry run, not actually creating maven repo')
    else:
      utils.upload_file_to_cloud_storage(library_jar, maven_destination)
      print('Maven repo root available at: %s' % archive.GetMavenUrl(is_main))

def Main(argv):
  (options, args) = ParseOptions(argv)
  if (len(args) > 0):
    raise Exception('Unsupported arguments')
  if not utils.is_bot() and not (options.dry_run or options.build_only):
    raise Exception('You are not a bot, don\'t archive builds. '
        + 'Use --dry-run or --build-only to test locally')
  if options.dry_run_output:
     MustBeExistingDirectory(options.dry_run_output)
  if options.build_only:
     MustBeExistingDirectory(options.build_only)
  if utils.is_bot():
    archive.SetRLimitToMax()

  # Make sure bazel is extracted in third_party.
  utils.DownloadFromGoogleCloudStorage(utils.BAZEL_SHA_FILE)
  utils.DownloadFromGoogleCloudStorage(utils.JAVA8_SHA_FILE)
  utils.DownloadFromGoogleCloudStorage(utils.JAVA11_SHA_FILE)

  for v in options.variant:
    BuildAndUpload(options, v)

if __name__ == '__main__':
  sys.exit(Main(sys.argv[1:]))
