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

from datetime import datetime
import argparse
import os
from os.path import join
import re
import shutil
import subprocess
import sys

import utils


def sed(pattern, replace, path):
    with open(path, "r") as sources:
        lines = sources.readlines()
    with open(path, "w") as sources:
        for line in lines:
            sources.write(re.sub(pattern, replace, line))


def GetGitHash(checkout_dir):
    return subprocess.check_output(
        ['git', '-C', checkout_dir, 'rev-parse',
         'HEAD']).decode('utf-8').strip()


def run(args):
    with utils.TempDir() as tmp_dir:
        use_existing_checkout = args.desugar_jdk_libs_checkout != None
        checkout_dir = (args.desugar_jdk_libs_checkout if use_existing_checkout
                        else join(tmp_dir, 'desugar_jdk_libs'))
        if (not use_existing_checkout):
            subprocess.check_call([
                'git', 'clone',
                'https://github.com/google/desugar_jdk_libs.git', checkout_dir
            ])
            if (args.desugar_jdk_libs_revision):
                subprocess.check_call([
                    'git', '-C', checkout_dir, 'checkout',
                    args.desugar_jdk_libs_revision
                ])
        print("Hack to workaround b/256723819")
        os.remove(
            join(checkout_dir, "jdk11", "src", "java.base", "share", "classes",
                 "java", "time", "format",
                 "DesugarDateTimeFormatterBuilder.java"))
        print("Building desugared library")
        bazel = os.path.join(utils.BAZEL_TOOL, 'lib', 'bazel', 'bin', 'bazel')
        with utils.ChangedWorkingDirectory(checkout_dir):
            subprocess.check_call([
                bazel, '--bazelrc=/dev/null', 'build',
                '--spawn_strategy=local', '--verbose_failures', ':desugar_jdk_libs_jdk11'
            ])

        openjdk_dir = join('third_party', 'openjdk')
        openjdk_subdir = 'desugar_jdk_libs_11'
        dest_dir = join(openjdk_dir, openjdk_subdir)
        src_dir = join(checkout_dir, 'bazel-bin', 'jdk11', 'src')

        metadata_files = ('LICENSE', 'README.google')
        for f in metadata_files:
            shutil.copyfile(join(dest_dir, f), join(tmp_dir, f))
        shutil.rmtree(dest_dir)
        os.remove(join(openjdk_dir, openjdk_subdir + '.tar.gz'))
        os.remove(join(openjdk_dir, openjdk_subdir + '.tar.gz.sha1'))
        os.mkdir(dest_dir)
        shutil.copyfile(
            join(src_dir, 'd8_java_base_selected_with_addon.jar'),
            join(dest_dir, 'desugar_jdk_libs.jar'))
        for f in metadata_files:
            shutil.copyfile(join(tmp_dir, f), join(dest_dir, f))
        desugar_jdk_libs_hash = os.path.join(dest_dir, 'desugar_jdk_libs_hash')
        with open(desugar_jdk_libs_hash, 'w') as desugar_jdk_libs_hash_writer:
            desugar_jdk_libs_hash_writer.write(GetGitHash(checkout_dir))
        sed('^Version: [0-9a-f]{40}$', 'Version: %s' % GetGitHash(checkout_dir),
            join(dest_dir, 'README.google'))
        sed('^Date: .*$', 'Date: %s' % datetime.today().strftime('%Y-%m-%d'),
            join(dest_dir, 'README.google'))

    print('Now run')
    print('  (cd %s; upload_to_google_storage.py -a --bucket r8-deps %s)' %
          (openjdk_dir, openjdk_subdir))


def main():
    args = parse_options()
    run(args)


def parse_options():
    parser = argparse.ArgumentParser(
        description='Script for updating third_party/openjdk/desugar_jdk_libs*')
    parser.add_argument(
        '--desugar-jdk-libs-checkout',
        '--desugar_jdk_libs_checkout',
        default=None,
        metavar=('<path>'),
        help='Use existing checkout of github.com/google/desugar_jdk_libs.')
    parser.add_argument(
        '--desugar-jdk-libs-revision',
        '--desugar_jdk_libs_revision',
        default=None,
        metavar=('<revision>'),
        help='Revision of github.com/google/desugar_jdk_libs to use.')
    args = parser.parse_args()
    return args


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