#!/usr/bin/env python3
# Copyright (c) 2023, 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 os.path
import shutil
import subprocess
import sys

import utils

# The local_maven_repository_generator orders the repositories by name, so
# prefix with X- to control the order, as many dependencies are present
# in several repositories. Save A- for additional local repository.
REPOSITORIES = [
    'B-Google=https://maven.google.com/',
    'C-Maven Central=https://repo1.maven.org/maven2/',
    "D-Gradle Plugins=https://plugins.gradle.org/m2/",
]

ANDROIDX_COLLECTION_VERSION = '1.6.0'
ANDROIDX_TRACING_VERSION = '2.0.0-alpha05'
ASM_VERSION = '9.9'  # When updating update tools/asmifier.py and Toolhelper as well.
FASTUTIL_VERSION = '7.2.1'
KOTLIN_METADATA_VERSION = '2.3.10'
# This version is both our kotlin compiler and Gradle's (current) kotlin compiler.
# If Gradle is upgraded, then this version might have to split into two and
# the dependencies untangled.
KOTLIN_VERSION = '2.2.21'
GUAVA_VERSION = '32.1.2-jre'
GSON_VERSION = '2.10.1'
JAVASSIST_VERSION = '3.29.2-GA'
MOCKITO_VERSION = '2.10.0'
TEST_RETRY_VERSION = '1.6.4'
SMALI_VERSION = '3.0.3'
ERROR_PRONE_VERSION = '2.18.0'
TESTNG_VERSION = '6.10'
JUNIT_JUPITER_VERSION = '5.14.3'
JUNIT_PLATFORM_VERSION = '1.14.3'
ZIPFLINGER_VERSION = '9.0.0'
DDMLIB_VERSION = '32.2.0'

# keepanno & resource shrinker dependencies
PROTOBUF_VERSION = '4.33.5'

# Resource shrinker dependency versions
AAPT2_PROTO_VERSION = '9.1.0-alpha09-14792394'
STUDIO_SDK_VERSION = '31.5.0-alpha04'

BUILD_DEPENDENCIES = [
    'androidx.collection:collection:{version}'.format(
        version=ANDROIDX_COLLECTION_VERSION),
    'androidx.tracing:tracing:{version}'.format(
        version=ANDROIDX_TRACING_VERSION),
    'androidx.tracing:tracing-desktop:{version}'.format(
        version=ANDROIDX_TRACING_VERSION),
    'androidx.tracing:tracing-wire:{version}'.format(
        version=ANDROIDX_TRACING_VERSION),
    'androidx.tracing:tracing-wire-desktop:{version}'.format(
        version=ANDROIDX_TRACING_VERSION),
    'com.google.code.gson:gson:{version}'.format(version=GSON_VERSION),
    'com.google.guava:guava:{version}'.format(version=GUAVA_VERSION),
    'it.unimi.dsi:fastutil:{version}'.format(version=FASTUTIL_VERSION),
    'org.ow2.asm:asm:{version}'.format(version=ASM_VERSION),
    'org.ow2.asm:asm-util:{version}'.format(version=ASM_VERSION),
    'org.ow2.asm:asm-commons:{version}'.format(version=ASM_VERSION),
    'com.google.errorprone:javac:9+181-r4173-1',
    'com.android.tools.build:aapt2-proto:{version}'.format(
        version=AAPT2_PROTO_VERSION),
    'com.android.tools.layoutlib:layoutlib-api:{version}'.format(
        version=STUDIO_SDK_VERSION),
    'com.android.tools:common:{version}'.format(version=STUDIO_SDK_VERSION),
    'com.android.tools:sdk-common:{version}'.format(version=STUDIO_SDK_VERSION),
    'com.android:zipflinger:{version}'.format(version=ZIPFLINGER_VERSION),
    'com.google.protobuf:protobuf-java:{version}'.format(
        version=PROTOBUF_VERSION),
    'org.jetbrains.kotlin:kotlin-assignment-compiler-plugin-embeddable:{version}'
    .format(version=KOTLIN_VERSION),
    'org.jetbrains.kotlin:kotlin-compiler-embeddable:{version}'.format(
        version=KOTLIN_VERSION),
    'org.jetbrains.kotlin:kotlin-gradle-plugin-api:{version}'.format(
        version=KOTLIN_VERSION),
    'org.jetbrains.kotlin:kotlin-gradle-plugin-idea:{version}'.format(
        version=KOTLIN_VERSION),
    'org.jetbrains.kotlin:kotlin-reflect:{version}'.format(
        version=KOTLIN_VERSION),
    'org.jetbrains.kotlin:kotlin-sam-with-receiver-compiler-plugin-embeddable:{version}'
    .format(version=KOTLIN_VERSION),
    'org.jetbrains.kotlin:kotlin-script-runtime:{version}'.format(
        version=KOTLIN_VERSION),
    'org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:{version}'.
    format(version=KOTLIN_VERSION),
    'org.jetbrains.kotlin:kotlin-stdlib-jdk8:{version}'.format(
        version=KOTLIN_VERSION),
    'org.jetbrains.kotlin:kotlin-tooling-core:{version}'.format(
        version=KOTLIN_VERSION),
    'org.jetbrains.kotlin:kotlin-build-tools-impl:{version}'.format(
        version=KOTLIN_VERSION),
    'org.jetbrains.kotlin:kotlin-metadata-jvm:{version}'.format(
        version=KOTLIN_METADATA_VERSION),
    'com.android.tools.ddms:ddmlib:{version}'.format(version=DDMLIB_VERSION),
]

TEST_DEPENDENCIES = [
    'com.android.tools.smali:smali:{version}'.format(version=SMALI_VERSION),
    'com.android.tools.smali:smali-util:{version}'.format(
        version=SMALI_VERSION),
    'com.google.errorprone:error_prone_core:{version}'.format(
        version=ERROR_PRONE_VERSION),
    'org.gradle:test-retry-gradle-plugin:{version}'.format(
        version=TEST_RETRY_VERSION),
    'org.javassist:javassist:{version}'.format(version=JAVASSIST_VERSION),
    'org.mockito:mockito-core:{version}'.format(version=MOCKITO_VERSION),
    'org.testng:testng:{version}'.format(version=TESTNG_VERSION),
    'org.junit.jupiter:junit-jupiter:{version}'.format(
        version=JUNIT_JUPITER_VERSION),
    'org.junit.vintage:junit-vintage-engine:{version}'.format(
        version=JUNIT_JUPITER_VERSION),
    'org.junit.platform:junit-platform-launcher:{version}'.format(
        version=JUNIT_PLATFORM_VERSION),
]

PLUGIN_DEPENDENCIES = [
    'org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:pom:{version}'
    .format(version=KOTLIN_VERSION),
    'com.google.protobuf:protobuf-gradle-plugin:0.9.4',
    'org.gradle.kotlin.kotlin-dsl:org.gradle.kotlin.kotlin-dsl.gradle.plugin:pom:6.4.2',
    'org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.9.10',
    'net.ltgt.errorprone:net.ltgt.errorprone.gradle.plugin:pom:3.0.1',
    'org.spdx.sbom:org.spdx.sbom.gradle.plugin:pom:0.4.0',
    # See https://github.com/FasterXML/jackson-core/issues/999.
    'ch.randelshofer:fastdoubleparser:0.8.0',
]


def dependencies_tar(dependencies_path):
    return os.path.join(os.path.dirname(dependencies_path),
                        os.path.basename(dependencies_path) + '.tar.gz')


def dependencies_tar_sha1(dependencies_path):
    return os.path.join(os.path.dirname(dependencies_path),
                        os.path.basename(dependencies_path) + '.tar.gz.sha1')


def remove_local_maven_repository(dependencies_path):
    if os.path.exists(dependencies_path):
        shutil.rmtree(dependencies_path)
    tar = dependencies_tar(dependencies_path)
    if os.path.exists(tar):
        os.remove(tar)
    sha1 = dependencies_tar_sha1(dependencies_path)
    if os.path.exists(sha1):
        os.remove(sha1)


def create_local_maven_repository(args, dependencies_path, repositories,
                                  dependencies):
    with utils.ChangedWorkingDirectory(args.studio):
        cmd = [
            os.path.join('tools', 'base', 'bazel', 'bazel'), 'run',
            '//tools/base/bazel:local_maven_repository_generator_cli', '--',
            '--repo-path', dependencies_path, '--fetch'
        ]
        for repository in repositories:
            cmd.extend(['--remote-repo', repository])
        for dependency in dependencies:
            cmd.append(dependency)
        subprocess.check_call(cmd)


def parse_options():
    result = argparse.ArgumentParser(
        description='Create local Maven repository woth dependencies')
    result.add_argument(
        '--studio',
        metavar=('<path>'),
        required=True,
        help='Path to a studio-main checkout (to get the tool '
        '//tools/base/bazel:local_maven_repository_generator_cli)')
    result.add_argument('--plugin-deps',
                        '--plugin_deps',
                        default=False,
                        action='store_true',
                        help='Build repository Gradle plugin dependncies')
    result.add_argument(
        '--include-maven-local',
        '--include_maven_local',
        metavar=('<path>'),
        default=False,
        help='Path to maven local repository to include as dependency source')
    result.add_argument('--no-upload',
                        '--no_upload',
                        default=False,
                        action='store_true',
                        help="Don't upload to Google CLoud Storage")
    return result.parse_args()


def set_utime(path):
    os.utime(path, (0, 0))
    for root, dirs, files in os.walk(path):
        for f in files:
            os.utime(os.path.join(root, f), (0, 0))
        for d in dirs:
            os.utime(os.path.join(root, d), (0, 0))


def main():
    args = parse_options()

    repositories = REPOSITORIES
    if args.include_maven_local:
        # Add the local repository as the first for it to take precedence.
        # Use A- prefix as current local_maven_repository_generator orderes by name.
        repositories = ['A-Local=file://%s' % args.include_maven_local
                       ] + REPOSITORIES

    dependencies = []

    if args.plugin_deps:
        dependencies_plugin_path = os.path.join(utils.THIRD_PARTY,
                                                'dependencies_plugin')
        remove_local_maven_repository(dependencies_plugin_path)
        print("Downloading to " + dependencies_plugin_path)
        create_local_maven_repository(args, dependencies_plugin_path,
                                      repositories, PLUGIN_DEPENDENCIES)
        set_utime(dependencies_plugin_path)
        dependencies.append('dependencies_plugin')
    else:
        dependencies_path = os.path.join(utils.THIRD_PARTY, 'dependencies')
        remove_local_maven_repository(dependencies_path)
        print("Downloading to " + dependencies_path)
        create_local_maven_repository(args, dependencies_path, repositories,
                                      BUILD_DEPENDENCIES + TEST_DEPENDENCIES)
        set_utime(dependencies_path)
        dependencies.append('dependencies')

    upload_cmds = []
    for dependency in dependencies:
        upload_cmds.append([
            'upload_to_google_storage.py', '-a', '--bucket', 'r8-deps',
            dependency
        ])

    if not args.no_upload:
        print("Uploading to Google Cloud Storage:")
        with utils.ChangedWorkingDirectory(utils.THIRD_PARTY):
            for cmd in upload_cmds:
                subprocess.check_call(cmd)
    else:
        print("Not uploading to Google Cloud Storage. " +
              "Run the following commands in %s to do so manually" %
              utils.THIRD_PARTY)
        for cmd in upload_cmds:
            print(" ".join(cmd))


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