// Copyright (c) 2016, 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 net.ltgt.gradle.errorprone.CheckSeverity
import org.gradle.internal.os.OperatingSystem
import tasks.DownloadDependency

plugins {
  id "net.ltgt.errorprone" version "2.0.2"
}

apply plugin: 'java'
apply plugin: 'idea'

ext {
    // When updating dependencies also update and run
    // tools/create_local_maven_with_dependencies.py
    androidSupportVersion = '25.4.0'
    asmVersion = '9.5'  // When updating update tools/asmifier.py, build.src and Toolhelper as well.
    javassistVersion = '3.29.2-GA'
    espressoVersion = '3.0.0'
    fastutilVersion = '7.2.1'
    guavaVersion = '31.1-jre'
    gsonVersion = '2.10.1'
    junitVersion = '4.13-beta-2'
    mockitoVersion = '2.10.0'
    // The kotlin version is only here to specify the kotlin language level,
    // all kotlin compilations are done in tests.
    kotlinVersion = '1.8.0'
    kotlinExtMetadataJVMVersion = '0.6.2'
    smaliVersion = '3.0.3'
    errorproneVersion = '2.18.0'
    testngVersion = '6.10'
}

repositories {
    maven {
        url uri('file:third_party/dependencies')
    }
}

if (project.hasProperty('with_code_coverage')) {
    apply plugin: 'jacoco'
}

// Custom source set for example tests and generated tests.
sourceSets {
    main {
        java {
            srcDirs = ['src/main/java', 'src/keepanno/java']
            // Exclude in old setup, resource shrinker is only compiled into R8 with 8.0
            exclude 'com/android/tools/r8/utils/resourceshrinker/*.java'
        }
        resources {
            srcDirs "third_party/api_database/api_database"
        }
    }
    main17 {
        java {
            srcDirs = ['src/main/java', 'src/keepanno/java']
            // Exclude in old setup, resource shrinker is only compiled into R8 with 8.0
            exclude 'com/android/tools/r8/utils/resourceshrinker/*.java'
        }
        resources {
            srcDirs "third_party/api_database/api_database"
        }
    }
    test {
        java {
            srcDirs = [
                    'src/test/java',
                    'src/test/bootstrap',
                    'build/generated/test/java',
            ]
        }
    }
    apiUsageSample {
        java {
            srcDirs = ['src/test/apiUsageSample', 'src/main/java']
            include 'com/android/tools/apiusagesample/*.java'
            include 'com/android/tools/r8/BaseCompilerCommandParser.java'
            include 'com/android/tools/r8/D8CommandParser.java'
            include 'com/android/tools/r8/R8CommandParser.java'
            include 'com/android/tools/r8/utils/FlagFile.java'
        }
    }
    cfSegments {
        java {
            srcDirs = ['third_party/classlib/java', 'src/cf_segments/java']
        }
        output.resourcesDir = 'build/classes/cfSegments'
    }
    debugTestResources {
        java {
            srcDirs = ['src/test/debugTestResources']
        }
        output.resourcesDir = 'build/classes/debugTestResources'
    }
    debugTestResourcesJava8 {
        java {
            srcDirs = ['src/test/debugTestResourcesJava8']
        }
        output.resourcesDir = 'build/classes/debugTestResourcesJava8'
    }
    examplesJava9 {
        java {
            srcDirs = ['src/test/examplesJava9']
        }
    }
    examplesJava10 {
        java {
            srcDirs = ['src/test/examplesJava10']
        }
    }
    examplesJava11 {
        java {
            srcDirs = ['src/test/examplesJava11']
        }
    }
    examplesJava17 {
        java {
            srcDirs = ['src/test/examplesJava17']
        }
    }
    examplesJava20 {
        java {
            srcDirs = ['src/test/examplesJava20']
        }
    }
    keepanno {
        java {
            srcDirs = ['src/keepanno/java']
            include 'com/android/tools/r8/keepanno/annotations/*.java'
        }
    }
}

// Ensure importing into IntelliJ IDEA use the same output directories as Gradle. In tests we
// use the output path for tests (ultimately through ToolHelper.getClassPathForTests()) and
// therefore these paths need to be the same. See https://youtrack.jetbrains.com/issue/IDEA-175172
// for context.
idea {
    sourceSets.all { SourceSet sources ->
        module {
            if (sources.name == "main") {
                sourceDirs += sources.java.srcDirs
                outputDir sources.output.classesDirs[0]
            } else {
                testSourceDirs += sources.java.srcDirs
                testOutputDir sources.output.classesDirs[0]
            }
        }
    }
}

dependencies {
    implementation "com.google.code.gson:gson:$gsonVersion"
    // Include all of guava when compiling the code, but exclude annotations that we don't
    // need from the packaging.
    compileOnly("com.google.guava:guava:$guavaVersion")
    implementation("com.google.guava:guava:$guavaVersion", {
        exclude group: 'com.google.errorprone'
        exclude group: 'com.google.code.findbugs'
        exclude group: 'com.google.j2objc'
        exclude group: 'org.codehaus.mojo'
        exclude group: 'com.google.guava', module: 'listenablefuture'
        exclude group: 'com.google.guava', module: 'failureaccess'
    })
    implementation group: 'it.unimi.dsi', name: 'fastutil', version: fastutilVersion
    implementation "org.jetbrains.kotlinx:kotlinx-metadata-jvm:$kotlinExtMetadataJVMVersion"
    implementation group: 'org.ow2.asm', name: 'asm', version: asmVersion
    implementation group: 'org.ow2.asm', name: 'asm-commons', version: asmVersion
    implementation group: 'org.ow2.asm', name: 'asm-tree', version: asmVersion
    implementation group: 'org.ow2.asm', name: 'asm-analysis', version: asmVersion
    implementation group: 'org.ow2.asm', name: 'asm-util', version: asmVersion

    main17Implementation "com.google.code.gson:gson:$gsonVersion"
    // Include all of guava when compiling the code, but exclude annotations that we don't
    // need from the packaging.
    main17CompileOnly("com.google.guava:guava:$guavaVersion")
    main17Implementation("com.google.guava:guava:$guavaVersion", {
        exclude group: 'com.google.errorprone'
        exclude group: 'com.google.code.findbugs'
        exclude group: 'com.google.j2objc'
        exclude group: 'org.codehaus.mojo'
    })
    main17Implementation group: 'it.unimi.dsi', name: 'fastutil', version: fastutilVersion
    main17Implementation "org.jetbrains.kotlinx:kotlinx-metadata-jvm:$kotlinExtMetadataJVMVersion"
    main17Implementation group: 'org.ow2.asm', name: 'asm', version: asmVersion
    main17Implementation group: 'org.ow2.asm', name: 'asm-commons', version: asmVersion
    main17Implementation group: 'org.ow2.asm', name: 'asm-tree', version: asmVersion
    main17Implementation group: 'org.ow2.asm', name: 'asm-analysis', version: asmVersion
    main17Implementation group: 'org.ow2.asm', name: 'asm-util', version: asmVersion

    testCompile "junit:junit:$junitVersion"
    testCompile "com.google.guava:guava:$guavaVersion"
    testCompile "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
    testCompile "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion"
    testCompile group: 'com.android.tools.smali', name: 'smali', version: smaliVersion
    testCompile files('third_party/jasmin/jasmin-2.4.jar')
    testCompile files('third_party/jdwp-tests/apache-harmony-jdwp-tests-host.jar')
    testCompile files('third_party/ddmlib/ddmlib.jar')
    testCompile group: 'org.ow2.asm', name: 'asm', version: asmVersion
    testCompile group: 'org.ow2.asm', name: 'asm-commons', version: asmVersion
    testCompile group: 'org.ow2.asm', name: 'asm-tree', version: asmVersion
    testCompile group: 'org.ow2.asm', name: 'asm-analysis', version: asmVersion
    testCompile group: 'org.ow2.asm', name: 'asm-util', version: asmVersion
    testCompile group: 'it.unimi.dsi', name: 'fastutil', version: fastutilVersion
    testCompile group: 'org.javassist', name: 'javassist', version: javassistVersion

    apiUsageSampleCompile sourceSets.main.output
    apiUsageSampleCompile "com.google.guava:guava:$guavaVersion"
    errorprone("com.google.errorprone:error_prone_core:$errorproneVersion")

    keepannoCompile group: 'org.ow2.asm', name: 'asm', version: asmVersion
    keepannoCompile "com.google.guava:guava:$guavaVersion"
}

def r8LibPath = "$buildDir/libs/r8lib.jar"
def r8LibExludeDepsPath = "$buildDir/libs/r8lib-exclude-deps.jar"
def r8DesugaredPath = "$buildDir/libs/r8desugared.jar"
def r8LibGeneratedKeepRulesPath = "$buildDir/generated/keep.txt"
def r8LibTestPath = "$buildDir/classes/r8libtest"
def java11ClassFiles = "$buildDir/classes/java/mainJava11"
def r8RetracePath = "$buildDir/libs/r8retrace.jar"
def r8RetraceExludeDepsPath = "$buildDir/libs/r8retrace-exclude-deps.jar"

def osString = OperatingSystem.current().isLinux() ? "linux" :
        OperatingSystem.current().isMacOsX() ? "mac" : "windows"

def cloudDependencies = [
        "tests"      : [
                "2017-10-04/art",
                "2016-12-19/art"
        ],
        "third_party": [
                "aapt2",
                "android_cts_baseline",
                "android_jar/libcore_latest",
                "android_jar/lib-v14",
                "android_jar/lib-v15",
                "android_jar/lib-v19",
                "android_jar/lib-v21",
                "android_jar/lib-v22",
                "android_jar/lib-v23",
                "android_jar/lib-v24",
                "android_jar/lib-v25",
                "android_jar/lib-v26",
                "android_jar/lib-v27",
                "android_jar/lib-v28",
                "android_jar/lib-v29",
                "android_jar/lib-v30",
                "android_jar/lib-v31",
                "android_jar/lib-v32",
                "android_jar/lib-v33",
                "android_jar/lib-v34",
                "android_jar/lib-master",
                "api_database/api_database",
                "api-outlining/simple-app-dump",
                "binary_compatibility_tests/compiler_api_tests",
                "bundletool/bundletool-1.11.0",
                "core-lambda-stubs",
                "dagger/2.41",
                "dart-sdk",
                "ddmlib",
                "examples",
                "examplesAndroidN",
                "examplesAndroidO",
                "examplesAndroidOLegacy",
                "examplesAndroidOGenerated",
                "examplesAndroidP",
                "examplesAndroidPGenerated",
                "gradle/gradle",
                "google/google-java-format/1.14.0",
                "google-java-format",
                "gson/gson-2.10.1",
                "guava/guava-32.1.2-android",
                "guava/guava-32.1.2-jre",
                "jacoco/0.8.2",
                "jacoco/0.8.6",
                "jasmin",
                "junit",
                "jdwp-tests",
                "jsr223-api-1.0",
                "rhino-1.7.10",
                "rhino-android-1.1.1",
                "kotlin/kotlin-compiler-1.3.72",
                "kotlin/kotlin-compiler-1.4.20",
                "kotlin/kotlin-compiler-1.5.0",
                "kotlin/kotlin-compiler-1.6.0",
                "kotlin/kotlin-compiler-1.7.0",
                "kotlin/kotlin-compiler-1.8.0",
                "kotlinx-coroutines-1.3.6",
                "kotlinR8TestResources",
                "multidex",
                "openjdk/custom_conversion",
                "openjdk/openjdk-rt-1.8",
                "openjdk/desugar_jdk_libs",
                "openjdk/desugar_jdk_libs_11",
                "openjdk/desugar_jdk_libs_releases/1.0.9",
                "openjdk/desugar_jdk_libs_releases/1.0.10",
                "openjdk/desugar_jdk_libs_releases/1.1.0",
                "openjdk/desugar_jdk_libs_releases/1.1.1",
                "openjdk/desugar_jdk_libs_releases/1.1.5",
                "openjdk/desugar_jdk_libs_releases/2.0.3",
                "openjdk/jdk-11-test",
                "opensource-apps/tivi",
                "proguard/proguard5.2.1",
                "proguard/proguard6.0.1",
                "proguard/proguard-7.0.0",
		"proguard/proguard-7.3.2",
                "retrace_benchmark",
                "retrace/binary_compatibility",
                "r8",
                "r8-releases/2.0.74",
                "r8-releases/3.2.54",
                "r8mappings",
                "smali"
        ],
        // All dex-vms have a fixed OS of Linux, as they are only supported on Linux, and will be run in a Docker
        // container on other platforms where supported.
        "tools"      : [
                "linux/art",
                "linux/art-5.1.1",
                "linux/art-6.0.1",
                "linux/art-7.0.0",
                "linux/art-8.1.0",
                "linux/art-9.0.0",
                "linux/art-10.0.0",
                "linux/host/art-12.0.0-beta4",
                "linux/host/art-13.0.0",
                "linux/host/art-14.0.0-beta3",
                "linux/host/art-master",
                "linux/dalvik",
                "linux/dalvik-4.0.4",
        ]
]

def cloudSystemDependencies = [
        linux: [
                "third_party": ["openjdk/openjdk-9.0.4/linux",
                                "openjdk/jdk8/linux-x86",
                                "openjdk/jdk-11/linux",
                                "openjdk/jdk-17/linux",
                                "openjdk/jdk-20/linux"],
        ],
        osx: [
                "third_party": ["openjdk/openjdk-9.0.4/osx",
                                "openjdk/jdk8/darwin-x86",
                                "openjdk/jdk-11/osx",
                                "openjdk/jdk-17/osx",
                                "openjdk/jdk-20/osx"],
        ],
        windows: [
                "third_party": ["openjdk/openjdk-9.0.4/windows",
                                "openjdk/jdk-11/windows",
                                "openjdk/jdk-17/windows",
                                "openjdk/jdk-20/windows"],
        ],
]

if (OperatingSystem.current().isWindows()) {
    cloudSystemDependencies.windows.each { entry ->
        cloudDependencies.get(entry.key).addAll(entry.value)
    }
} else if (OperatingSystem.current().isLinux()) {
    cloudSystemDependencies.linux.each { entry ->
        cloudDependencies.get(entry.key).addAll(entry.value)
    }
} else if (OperatingSystem.current().isMacOsX()) {
    cloudSystemDependencies.osx.each { entry ->
        cloudDependencies.get(entry.key).addAll(entry.value)
    }
} else {
    println "WARNING: Unsupported system: " + OperatingSystem.current()
}

def getDownloadDepsTaskName(entryKey, entryFile) {
    return "download_deps_${entryKey}_${entryFile.replace('/', '_').replace('\\', '_')}"
}

cloudDependencies.each { entry ->
    entry.value.each { entryFile ->
        task (getDownloadDepsTaskName(entry.key, entryFile), type: DownloadDependency) {
            type DownloadDependency.Type.GOOGLE_STORAGE
            dependency "${entry.key}/${entryFile}"
        }
    }
}

def x20Dependencies = [
    "third_party": [
        "benchmarks/kotlin-benches",
        "chrome/chrome_200430",
        "chrome/monochrome_public_minimal_apks/chrome_200520",
        "chrome/clank_google3_prebuilt",
        "classlib",
        "cf_segments",
        "desugar/desugar_20180308",
        "internal/issue-127524985",
        "framework",
        "gmail/gmail_android_180826.15",
        "gmscore/gmscore_v10",
        "gmscore/latest",
        "nest/nest_20180926_7c6cfb",
        "proguard/proguard_internal_159423826",
        "proguardsettings",
        "proto",
        "protobuf-lite",
        "retrace_internal",
        "youtube/youtube.android_17.19"
    ],
]

x20Dependencies.each { entry ->
    entry.value.each { entryFile ->
        task "${getDownloadDepsTaskName(entry.key, entryFile)}"(type: DownloadDependency) {
            type DownloadDependency.Type.X20
            dependency "${entry.key}/${entryFile}"
        }
    }
}

task downloadOpenJDKrt {
   cloudDependencies.each { entry ->
        entry.value.each { entryFile ->
            if (entryFile.contains("openjdk-rt")) {
                dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
            }
        }
    }
}

task downloadAndroidCts {
    cloudDependencies.each { entry ->
        entry.value.each { entryFile ->
            if (entryFile.contains("android_cts_baseline")) {
                dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
            }
        }
    }
}

task downloadCloudDeps() {
    cloudDependencies.each { entry ->
        entry.value.each { entryFile ->
            dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
        }
    }
}

task downloadX20Deps() {
    x20Dependencies.each { entry ->
        entry.value.each { entryFile ->
            dependsOn "${getDownloadDepsTaskName(entry.key, entryFile)}"
        }
    }
}

task downloadDeps {
    dependsOn downloadCloudDeps
    if (!project.hasProperty('no_internal')) {
        dependsOn downloadX20Deps
    }
}

allprojects {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
}

// TODO(ricow): Remove debug prints
println("NOTE: Current operating system: " + OperatingSystem.current())
println("NOTE: Current operating system isWindows: " + OperatingSystem.current().isWindows())

// Check if running with the JDK location from tools/jdk.py.
if (OperatingSystem.current().isWindows()) {
    println "NOTE: Running with JDK: " + org.gradle.internal.jvm.Jvm.current().javaHome
    compileJava.options.encoding = "UTF-8"
    compileTestJava.options.encoding = "UTF-8"
} else {
    def javaHomeOut = new StringBuilder()
    def javaHomeErr = new StringBuilder()
    def javaHomeProc = './tools/jdk.py'.execute([], projectDir)
    javaHomeProc.waitForProcessOutput(javaHomeOut, javaHomeErr)
    def jdkHome = new File(javaHomeOut.toString().trim())
    if (!jdkHome.exists()) {
        println "WARNING: Failed to find the ./tools/jdk.py specified JDK: " + jdkHome
    } else if (jdkHome != org.gradle.internal.jvm.Jvm.current().javaHome) {
        println("WARNING: Gradle is running in a non-pinned Java"
                + ". Gradle Java Home: " + org.gradle.internal.jvm.Jvm.current().javaHome
                + ". Expected: " + jdkHome)
    } else {
        println("NOTE: Running with jdk from tools/jdk.py: " + jdkHome)
    }
}

compileJava.dependsOn downloadCloudDeps

sourceSets.configureEach { sourceSet ->
    tasks.named(sourceSet.compileJavaTaskName).configure {
        // Default disable errorprone (enabled and setup below).
        options.errorprone.enabled = false
        options.compilerArgs << '-Xlint:unchecked'
        // Run all compilation tasks in a forked subprocess.
        options.fork = true
        // Javac often runs out of stack space when compiling the tests.
        // Increase the stack size for the javac process.
        options.forkOptions.jvmArgs << "-Xss256m"
        // Test compilation is sometimes hitting the default limit at 1g, increase it.
        options.forkOptions.jvmArgs << "-Xmx3g"
    }
}

def setJdkCompilationWithCompatibility(String sourceSet, String javaHome, JavaVersion compatibility, boolean enablePreview) {
    tasks.named(sourceSet).get().configure {
        def jdkDir = "third_party/openjdk/${javaHome}/"
        options.fork = true
        options.forkOptions.jvmArgs = []
        if (enablePreview) {
            options.compilerArgs.add('--enable-preview')
        }
        if (OperatingSystem.current().isLinux()) {
            dependsOn getDownloadDepsTaskName("third_party", "openjdk/" + javaHome + "/linux")
            options.forkOptions.javaHome = file(jdkDir + 'linux')
        } else if (OperatingSystem.current().isMacOsX()) {
            dependsOn getDownloadDepsTaskName("third_party", "openjdk/" + javaHome + "/osx")
            options.forkOptions.javaHome = compatibility > JavaVersion.VERSION_1_9
                    ? file(jdkDir + 'osx/Contents/Home')
                    : file(jdkDir + 'osx')
        } else {
            dependsOn getDownloadDepsTaskName("third_party", "openjdk/" + javaHome + "/windows")
            options.forkOptions.javaHome = file(jdkDir + 'windows')
        }
        sourceCompatibility = compatibility
        targetCompatibility = compatibility
    }
}

setJdkCompilationWithCompatibility(
        sourceSets.main.compileJavaTaskName,
        'jdk-11',
        JavaVersion.VERSION_11,
        false);

setJdkCompilationWithCompatibility(
        sourceSets.examplesJava9.compileJavaTaskName,
        'openjdk-9.0.4',
        JavaVersion.VERSION_1_9,
        false)
setJdkCompilationWithCompatibility(
        sourceSets.examplesJava10.compileJavaTaskName,
        'jdk-11',
        JavaVersion.VERSION_1_10,
        false)
setJdkCompilationWithCompatibility(
        sourceSets.main17.compileJavaTaskName,
        'jdk-17',
        JavaVersion.VERSION_17,
        false)
setJdkCompilationWithCompatibility(
        sourceSets.examplesJava11.compileJavaTaskName,
        'jdk-11',
        JavaVersion.VERSION_11,
        false)
setJdkCompilationWithCompatibility(
        sourceSets.examplesJava17.compileJavaTaskName,
        'jdk-17',
        JavaVersion.VERSION_17,
        false)
setJdkCompilationWithCompatibility(
        sourceSets.examplesJava20.compileJavaTaskName,
        'jdk-20',
        // TODO(b/218293990): Update Gradle to get JavaVersion.VERSION_18.
        JavaVersion.VERSION_17,
        false)

if (!project.hasProperty('without_error_prone') &&
        // Don't enable error prone on Java 8 as the plugin setup does not support it.
        !org.gradle.internal.jvm.Jvm.current().javaVersion.java8) {
    compileJava {

        // Enable error prone for D8/R8 main sources.
        options.errorprone.enabled = true

        // Make all warnings errors. Warnings that we have chosen not to fix (or suppress) are
        // disabled outright below.
        options.compilerArgs << "-Werror"

        // Increase number of reported errors to 1000 (default is 100).
        options.compilerArgs << "-Xmaxerrs"
        options.compilerArgs << "1000"

        // Non-default / Experimental checks - explicitly enforced.
        options.errorprone.check('RemoveUnusedImports', CheckSeverity.ERROR)
        options.errorprone.check('InconsistentOverloads', CheckSeverity.ERROR)
        options.errorprone.check('MissingDefault', CheckSeverity.ERROR)
        options.errorprone.check('MultipleTopLevelClasses', CheckSeverity.ERROR)
        options.errorprone.check('NarrowingCompoundAssignment', CheckSeverity.ERROR)

        // Warnings that cause unwanted edits (e.g., inability to write informative asserts).
        options.errorprone.check('AlreadyChecked', CheckSeverity.OFF)

        // JavaDoc related warnings. Would be nice to resolve but of no real consequence.
        options.errorprone.check('InvalidLink', CheckSeverity.OFF)
        options.errorprone.check('InvalidBlockTag', CheckSeverity.OFF)
        options.errorprone.check('InvalidInlineTag', CheckSeverity.OFF)
        options.errorprone.check('EmptyBlockTag', CheckSeverity.OFF)
        options.errorprone.check('MissingSummary', CheckSeverity.OFF)
        options.errorprone.check('UnrecognisedJavadocTag', CheckSeverity.OFF)
        options.errorprone.check('AlmostJavadoc', CheckSeverity.OFF)

        // Moving away from identity and canonical items is not planned.
        options.errorprone.check('IdentityHashMapUsage', CheckSeverity.OFF)
    }
}

task consolidatedLicense {
    def license = new File(new File(buildDir, 'generatedLicense'), 'LICENSE')

    inputs.files files('LICENSE', 'LIBRARY-LICENSE') + fileTree(dir: 'library-licensing')
    def runtimeClasspath = configurations.findByName("runtimeClasspath")
    inputs.files { runtimeClasspath.getResolvedConfiguration().files }

    outputs.files license

    doLast {
        def dependencies = []
        runtimeClasspath.resolvedConfiguration.resolvedArtifacts.each {
            def identifier = (ModuleComponentIdentifier) it.id.componentIdentifier
            dependencies.add("${identifier.group}:${identifier.module}")
        }
        def libraryLicenses = file('LIBRARY-LICENSE').text
        dependencies.each {
            if (!libraryLicenses.contains("- artifact: $it")) {
                 throw new GradleException("No license for $it in LIBRARY_LICENSE")
            }
        }

        license.getParentFile().mkdirs()
        license.createNewFile()
        license.text = "This file lists all licenses for code distributed.\n"
        license.text += "All non-library code has the following 3-Clause BSD license.\n"
        license.text += "\n"
        license.text += "\n"
        license.text += file('LICENSE').text
        license.text += "\n"
        license.text += "\n"
        license.text += "Summary of distributed libraries:\n"
        license.text += "\n"
        license.text += libraryLicenses
        license.text += "\n"
        license.text += "\n"
        license.text += "Licenses details:\n"
        fileTree(dir: 'library-licensing').getFiles().stream().sorted().forEach { file ->
            license.text += "\n"
            license.text += "\n"
            license.text += file.text
        }
    }
}

def repackageDepFile(file) {
    if (file.getName().endsWith('.jar')) {
        return zipTree(file).matching {
            exclude '**/module-info.class'
            exclude 'META-INF/maven/**'
            exclude 'META-INF/LICENSE.txt'
            exclude 'META-INF/MANIFEST.MF'
        }
    } else {
        return fileTree(file)
    }
}

task repackageDeps(type: Jar) {
    dependsOn downloadCloudDeps
    dependsOn project.configurations.runtimeClasspath
    project.configurations.runtimeClasspath.forEach {
        from repackageDepFile(it)
    }
    archiveFileName = 'deps_all.jar'
}

task repackageTestDeps(type: Jar) {
    dependsOn downloadCloudDeps
    dependsOn project.configurations.testCompile
    project.configurations.testCompile.forEach {
        from repackageDepFile(it)
    }
    archiveFileName = 'test_deps_all.jar'
}

task repackageSources(type: Jar) {
    // If this fails then remove all generated folders from
    // build/classes/java/test that is not {com,dalvik}
    from sourceSets.main.output
    archiveFileName = 'sources_main.jar'
}

task repackageSources17(type: Jar) {
    from sourceSets.main17.output
    archiveFileName = 'sources_main_17.jar'
}

def r8CreateTask(name, baseName, sources, includeLibraryLicenses, includeSwissArmyKnife) {
    return tasks.create("r8Create${name}", Jar) {
        entryCompression ZipEntryCompression.STORED
        dependsOn sources
        dependsOn files('LICENSE')
        if (includeLibraryLicenses) {
            from consolidatedLicense.outputs.files
        } else {
            from files('LICENSE')
        }
        from sources.collect { zipTree(it) }
        exclude "$buildDir/classes/**"
        archiveFileName = baseName
        if (includeSwissArmyKnife) {
            manifest {
                attributes 'Main-Class': 'com.android.tools.r8.SwissArmyKnife'
            }
        }
        exclude "META-INF/*.kotlin_module"
        exclude "**/*.kotlin_metadata"
    }
}

def r8RelocateTask(r8Task, output) {
    return tasks.create("r8Relocate_${r8Task.name}", Exec) {
        dependsOn r8WithDeps
        dependsOn r8Task
        outputs.file output
        workingDir = projectDir
        inputs.files r8Task.outputs.files + r8WithDeps.outputs.files
        commandLine baseCompilerCommandLine([
                "relocator",
                "--input",
                r8Task.outputs.files[0],
                "--output",
                output,
                "--map",
                "com.google.common.**->com.android.tools.r8.com.google.common",
                "--map",
                "com.google.gson.**->com.android.tools.r8.com.google.gson",
                "--map",
                "com.google.thirdparty.**->com.android.tools.r8.com.google.thirdparty",
                "--map",
                "org.objectweb.asm.**->com.android.tools.r8.org.objectweb.asm",
                "--map",
                "it.unimi.dsi.fastutil.**->com.android.tools.r8.it.unimi.dsi.fastutil",
                "--map",
                "kotlin.**->com.android.tools.r8.jetbrains.kotlin",
                "--map",
                "kotlinx.**->com.android.tools.r8.jetbrains.kotlinx",
                "--map",
                "org.jetbrains.**->com.android.tools.r8.org.jetbrains",
                "--map",
                "org.intellij.**->com.android.tools.r8.org.intellij",
                "--map",
                "org.checkerframework.**->com.android.tools.r8.org.checkerframework"
        ])
    }
}

task r8WithDeps {
    dependsOn repackageSources
    dependsOn repackageDeps
    inputs.files ([repackageSources.outputs, repackageDeps.outputs])
    def r8Task = r8CreateTask(
            'WithDeps',
            'r8_with_deps.jar',
            repackageSources.outputs.files + repackageDeps.outputs.files,
            true,
            true)
    dependsOn r8Task
    outputs.files r8Task.outputs.files
}

task r8WithDeps17 {
    dependsOn repackageSources17
    dependsOn repackageDeps
    inputs.files ([repackageSources17.outputs, repackageDeps.outputs])
    def r8Task = r8CreateTask(
            'WithDeps17',
            'r8_with_deps_17.jar',
            repackageSources17.outputs.files + repackageDeps.outputs.files,
            true,
            true)
    dependsOn r8Task
    outputs.files r8Task.outputs.files
}

task r8WithRelocatedDeps {
    def output = "${buildDir}/libs/r8_with_relocated_deps.jar"
    dependsOn r8RelocateTask(r8WithDeps, output)
    inputs.files r8WithDeps.outputs.files
    outputs.file output
}

task r8WithRelocatedDeps17 {
    def output = "${buildDir}/libs/r8_with_relocated_deps_17.jar"
    dependsOn r8RelocateTask(r8WithDeps17, output)
    inputs.files r8WithDeps17.outputs.files
    outputs.file output
}

task r8WithoutDeps {
    dependsOn repackageSources
    inputs.files repackageSources.outputs
    def r8Task = r8CreateTask(
            'WithoutDeps',
            'r8_without_deps.jar',
            repackageSources.outputs.files,
            false,
            true)
    dependsOn r8Task
    outputs.files r8Task.outputs.files
}

task r8(type: Copy) {
    def r8Task = project.hasProperty("exclude_deps")
            ? r8WithoutDeps : r8WithRelocatedDeps
    dependsOn r8Task
    from r8Task.outputs.files[0]
    into file("${buildDir}/libs")
    rename { String fileName -> "r8.jar" }
    outputs.file "${buildDir}/libs/r8.jar"
}

task r8NoManifestWithoutDeps {
    dependsOn repackageSources
    inputs.files repackageSources.outputs
    def r8Task = r8CreateTask(
            'NoManifestWithoutDeps',
            'r8_no_manifest_without_deps.jar',
            repackageSources.outputs.files,
            false,
            false)
    dependsOn r8Task
    outputs.files r8Task.outputs.files
}

task r8NoManifestWithDeps {
    dependsOn repackageSources
    inputs.files ([repackageSources.outputs, repackageDeps.outputs])
    def r8Task = r8CreateTask(
            'NoManifestWithDeps',
            'r8_no_manifest_with_deps.jar',
            repackageSources.outputs.files + repackageDeps.outputs.files,
            true,
            false)
    dependsOn r8Task
    outputs.files r8Task.outputs.files
}

task r8NoManifestWithRelocatedDeps {
    def output = "${buildDir}/libs/r8_no_manifest_with_relocated_deps.jar"
    dependsOn r8RelocateTask(r8NoManifestWithDeps, output)
    inputs.files r8NoManifestWithDeps.outputs.files
    outputs.file output
}

task r8NoManifest(type: Copy) {
    def r8Task = project.hasProperty("exclude_deps")
            ? r8NoManifestWithoutDeps : r8NoManifestWithRelocatedDeps
    dependsOn r8Task
    from r8Task.outputs.files[0]
    into file("${buildDir}/libs")
    rename { String fileName -> "r8_no_manifest.jar" }
    outputs.file "${buildDir}/libs/r8_no_manifest.jar"
}

def baseCompilerCommandLine(compiler, args = []) {
    // Execute r8 commands against a stable r8 with dependencies.
    // TODO(b/139725780): See if we can remove or lower the heap size (-Xmx8g).
    return [org.gradle.internal.jvm.Jvm.current().getJavaExecutable(),
            "-Xmx8g", "-ea", "-jar", r8WithDeps.outputs.files[0]] + compiler + args
}

def baseR8CommandLine(args = []) {
    // Execute r8 commands against a stable r8 with dependencies.
    return baseCompilerCommandLine("r8", args)
}

def baseD8CommandLine(args = []) {
    // Execute r8 commands against a stable r8 with dependencies.
    return baseCompilerCommandLine("d8", args)
}

def r8CfCommandLine(input, output, pgConfs = [], args = ["--release"], libs = []) {
    def allArgs = [
            "--classfile",
            input,
            "--output", output,
            "--pg-map-output", output + ".map",
            "--partition-map-output", output + "_map.zip",
            "--lib", org.gradle.internal.jvm.Jvm.current().javaHome,
    ] + args + libs.collectMany { ["--lib", it] } + pgConfs.collectMany { ["--pg-conf", it] }
    return baseR8CommandLine(allArgs)
}

def d8CfCommandLine(input, output, args = ["--release"], libs = []) {
    def allArgs = [
            "--classfile",
            input,
            "--output", output,
            "--lib", "third_party/openjdk/openjdk-rt-1.8/rt.jar"
    ] + args + libs.collectMany { ["--lib", it] }
    return baseD8CommandLine(allArgs)
}

def r8LibCreateTask(
    name, pgConfs = [], r8Task, output, libs = [], classpath = [], excldeps=false, debug=false) {
    return tasks.create("r8Lib${name}", Exec) {
        inputs.files ([pgConfs, r8WithRelocatedDeps.outputs, r8Task.outputs])
        outputs.file output
        dependsOn downloadOpenJDKrt
        dependsOn r8WithRelocatedDeps
        dependsOn r8Task
        commandLine ([
                "python3", "tools/create_r8lib.py",
                "--r8jar", r8Task.outputs.files[0],
                "--output", output]
                + (excldeps ? ['--excldeps-variant'] : [])
                + (debug ? ['--debug-variant'] : [])
                + (pgConfs.collectMany { ["--pg-conf", it] })
                + (libs.collectMany { ["--lib", it] })
                + (classpath.collectMany { ["--classpath", it] }))
        workingDir = projectDir
    }
}

task testJarSources(type: Jar, dependsOn: [testClasses]) {
    archiveFileName = "r8testsbase.jar"
    from sourceSets.test.output
    // We only want to include tests that use R8 when generating keep rules for applymapping.
    include "com/android/tools/r8/**"
    include "android/**"
    include "dalvik/**"
}

task testJar(type: Exec) {
    dependsOn r8WithDeps
    dependsOn testJarSources
    def output = "$buildDir/libs/r8tests.jar"
    outputs.file output
    workingDir = projectDir
    inputs.files (testJarSources.outputs.files + r8WithDeps.outputs.files)
    commandLine baseCompilerCommandLine([
            "relocator",
            "--input",
            testJarSources.outputs.files[0],
            "--output",
            output,
            "--map",
            "kotlinx.metadata.**->com.android.tools.r8.jetbrains.kotlinx.metadata"
    ])
}

task generateR8LibKeepRules(type: Exec) {
    // Depend on r8WithRelocatedDeps to ensure that we do not have external
    // dependencies crossing the boundary.
    dependsOn r8WithDeps
    dependsOn r8NoManifestWithRelocatedDeps
    dependsOn testJar
    dependsOn repackageTestDeps
    dependsOn downloadOpenJDKrt
    inputs.files ([
            r8WithDeps.outputs,
            r8NoManifestWithRelocatedDeps.outputs,
            repackageDeps.outputs,
            repackageTestDeps.outputs,
            testJar.outputs])
    outputs.file r8LibGeneratedKeepRulesPath
    commandLine baseCompilerCommandLine([
            "tracereferences",
            "--keep-rules",
            "--allowobfuscation",
            "--lib",
            "third_party/openjdk/openjdk-rt-1.8/rt.jar",
            "--lib",
            repackageDeps.outputs.files[0],
            "--lib",
            repackageTestDeps.outputs.files[0],
            "--target",
            r8NoManifestWithRelocatedDeps.outputs.files[0],
            "--source",
            testJar.outputs.files[0],
            "--output",
            r8LibGeneratedKeepRulesPath])
    workingDir = projectDir
}

task R8Lib {
    dependsOn r8LibCreateTask(
            "Main",
            ["src/main/keep.txt", generateR8LibKeepRules.outputs.files[0]],
            r8NoManifestWithRelocatedDeps,
            r8LibPath
    ).dependsOn(generateR8LibKeepRules)
    inputs.files r8NoManifestWithRelocatedDeps.outputs.files
    outputs.file r8LibPath
}

task R8LibNoDeps {
    dependsOn r8LibCreateTask(
            "MainNoDeps",
            ["src/main/keep.txt"],
            r8NoManifestWithoutDeps,
            r8LibExludeDepsPath,
            [],
            repackageDeps.outputs.files,
            true,
    ).dependsOn(repackageDeps)
    inputs.files ([r8NoManifestWithoutDeps.outputs, repackageDeps.outputs])
    outputs.file r8LibExludeDepsPath
}

task R8Desugared(type: Exec) {
    dependsOn downloadOpenJDKrt
    dependsOn r8NoManifestWithRelocatedDeps
    inputs.files r8NoManifestWithRelocatedDeps.outputs.files
    commandLine d8CfCommandLine(
            r8NoManifestWithRelocatedDeps.outputs.files[0],
            r8DesugaredPath,
            ["--release"])
    workingDir = projectDir
    outputs.file r8DesugaredPath
}

task R8Retrace {
    dependsOn R8Lib
    dependsOn r8LibCreateTask(
            "Retrace",
            ["src/main/keep_retrace.txt"],
            R8Lib,
            r8RetracePath,
            [],
            [],
            false,
            true
    ).dependsOn(R8Lib)
    outputs.file r8RetracePath
}

task R8RetraceNoDeps {
    dependsOn R8LibNoDeps
    dependsOn r8LibCreateTask(
            "RetraceNoDeps",
            ["src/main/keep_retrace.txt"],
            R8LibNoDeps,
            r8RetraceExludeDepsPath,
            [],
            repackageDeps.outputs.files,
            true,
            true,
    ).dependsOn(R8LibNoDeps)
    outputs.file r8RetraceExludeDepsPath
}

task sourceJar(type: Jar, dependsOn: classes) {
    classifier = 'src'
    from sourceSets.main.allSource
}

task keepAnnoJar(type: Jar) {
    archiveFileName = "keepanno-annotations.jar"
    from sourceSets.keepanno.output
}

artifacts {
    archives sourceJar
}

task createArtTests(type: Exec) {
    def outputDir = "build/generated/test/java/com/android/tools/r8/art"
    def createArtTestsScript = "tools/create_art_tests.py"
    inputs.files files("tests/2017-10-04/art.tar.gz", createArtTestsScript)
    outputs.dir outputDir
    dependsOn downloadDeps
    commandLine "python3", createArtTestsScript
    workingDir = projectDir
}

compileTestJava {
    dependsOn createArtTests
}

task buildCfSegments(type: Jar, dependsOn: downloadDeps) {
    from sourceSets.cfSegments.output
    archiveFileName = 'cf_segments.jar'
    destinationDir file('build/libs')
}

task buildR8ApiUsageSample(type: Jar) {
    from sourceSets.apiUsageSample.output
    archiveFileName = 'r8_api_usage_sample.jar'
    destinationDir file('tests')
}

task buildApiSampleJars {
    dependsOn buildR8ApiUsageSample
}

def buildExampleJarsCreateTask(javaVersion, sourceSet) {
    return tasks.create("buildExample${javaVersion}Jars") {
        def examplesDir = file("src/test/examples${javaVersion}")
        examplesDir.eachDir { dir ->
            def name = dir.getName();
            def exampleOutputDir = file("build/test/examples${javaVersion}");
            def jarName = "${name}.jar"
            dependsOn "jar_examples${javaVersion}_${name}"
            task "jar_examples${javaVersion}_${name}"(type: Jar) {
                archiveName = jarName
                destinationDir = exampleOutputDir
                from sourceSet.output
                include "**/" + name + "/**/*.class"
            }
        }
    }
}

buildExampleJarsCreateTask("Java9", sourceSets.examplesJava9)
buildExampleJarsCreateTask("Java10", sourceSets.examplesJava10)
buildExampleJarsCreateTask("Java11", sourceSets.examplesJava11)
buildExampleJarsCreateTask("Java17", sourceSets.examplesJava17)
buildExampleJarsCreateTask("Java20", sourceSets.examplesJava20)

task buildExamples {
    if (OperatingSystem.current().isMacOsX() || OperatingSystem.current().isWindows()) {
        logger.lifecycle("WARNING: Testing (including building examples) is only partially supported on your " +
                "platform (" + OperatingSystem.current().getName() + ").")
    } else if (!OperatingSystem.current().isLinux()) {
      logger.lifecycle("WARNING: Testing (including building examples) is not supported on your platform. " +
          "It is fully supported on Linux and partially supported on Mac OS and Windows")
      return;
    }
    dependsOn buildExampleJava9Jars
    dependsOn buildExampleJava10Jars
    dependsOn buildExampleJava11Jars
    dependsOn buildExampleJava17Jars
    dependsOn buildExampleJava20Jars
}

tasks.withType(Test) {
    println("NOTE: Number of processors " + Runtime.runtime.availableProcessors())
    def userDefinedCoresPerFork = System.getenv('R8_GRADLE_CORES_PER_FORK')
    def processors = Runtime.runtime.availableProcessors()
    // See https://docs.gradle.org/current/dsl/org.gradle.api.tasks.testing.Test.html.
    if (userDefinedCoresPerFork) {
      maxParallelForks = processors.intdiv(userDefinedCoresPerFork.toInteger()) ?: 1
    } else {
      // On normal work machines this seems to give the best test execution time (without freezing)
      maxParallelForks = processors.intdiv(3) ?: 1
      // On low cpu count machines (bots) we under subscribe, so increase the count.
      if (processors == 32) {
        maxParallelForks = 15
      }
    }
    println("NOTE: Max parallel forks " + maxParallelForks)

    forkEvery = 0
    if (project.hasProperty('disable_assertions')) {
        enableAssertions = false
    }
    // TODO(b/124091860): Increase the max heap size to avoid OOM when running tests.
    if (project.hasProperty('test_xmx')) {
      maxHeapSize = project.property('test_xmx')
    } else {
      maxHeapSize = "4G"
    }
}

task buildPreNJdwpTestsJar(type: Jar) {
    archiveFileName = 'jdwp-tests-preN.jar'
    from zipTree('third_party/jdwp-tests/apache-harmony-jdwp-tests-host.jar')
    // Exclude the classes containing java8
    exclude 'org/apache/harmony/jpda/tests/jdwp/InterfaceType/*.class'
    exclude 'org/apache/harmony/jpda/tests/jdwp/ObjectReference/InvokeMethodDefault*.class'
    includeEmptyDirs = false
}

task generateR8TestKeepRules {
    def path = "build/generated/r8tests-keep.txt"
    outputs.file path
    dependsOn R8Lib
    doLast {
        file(path).write """-keep class ** { *; }
-dontshrink
-dontoptimize
-keepattributes *
-applymapping ${R8Lib.outputs.files[0]}.map
"""
    }
}

task buildR8LibCfTestDeps(type: Exec) {
    def outputPath = "build/libs/r8libtestdeps-cf.jar"
    dependsOn downloadDeps
    dependsOn r8NoManifest
    dependsOn R8Lib
    dependsOn generateR8TestKeepRules
    dependsOn testJar
    // Take all .jar files as libraries and append the generated test classes in classes/java/test.
    def addedLibraries = sourceSets.test.runtimeClasspath.findAll { pkg ->
        return pkg.toString().endsWith(".jar")
    } + ["${buildDir}/classes/java/test"]
    inputs.files testJar.outputs.files +
            generateR8TestKeepRules.outputs.files +
            R8Lib.outputs
    commandLine = r8CfCommandLine(
            testJar.outputs.files[0],
            outputPath,
            [generateR8TestKeepRules.outputs.files[0]],
            ["--debug", "--classpath", r8NoManifest.outputs.files[0]],
            r8NoManifest.outputs.files + addedLibraries)
    workingDir = projectDir
    outputs.file outputPath
}

task configureTestForR8Lib(type: Copy) {
    dependsOn testJar
    inputs.files buildR8LibCfTestDeps.outputs
    dependsOn R8Lib
    delete r8LibTestPath
    from zipTree(buildR8LibCfTestDeps.outputs.files[0])
    def examplesDir = file("build/test")
    if (examplesDir.exists()) {
        examplesDir.eachDir { dir ->
            from ("${buildDir}/test/${dir.getName()}/classes")
        }
    }
    from ("${buildDir}/runtime/examples")
    into r8LibTestPath
    outputs.dir r8LibTestPath
}

def shouldRetrace() {
    return project.hasProperty('r8lib') || project.hasProperty('r8lib_no_deps')
}

def retrace(Throwable exception) {
    def out = new StringBuffer()
    def err = new StringBuffer()
    def command = "python3 tools/retrace.py --quiet"
    def header = "RETRACED STACKTRACE";
    out.append("\n--------------------------------------\n")
    out.append("${header}\n")
    out.append("--------------------------------------\n")
    Process process = command.execute()
    def processIn = new PrintStream(process.getOut())
    process.consumeProcessOutput(out, err)
    exception.printStackTrace(processIn)
    processIn.flush()
    processIn.close()
    def errorDuringRetracing = process.waitFor() != 0
    if (errorDuringRetracing) {
        out.append("ERROR DURING RETRACING\n")
        out.append(err.toString())
    }
    if (project.hasProperty('print_obfuscated_stacktraces') || errorDuringRetracing) {
        out.append("\n\n--------------------------------------\n")
        out.append("OBFUSCATED STACKTRACE\n")
        out.append("--------------------------------------\n")
    }
    return out.toString()
}

def printStackTrace(TestResult result) {
    filterStackTraces(result)
    if (shouldRetrace()) {
        def exception = new Exception(retrace(result.exception))
        exception.setStackTrace([] as StackTraceElement[])
        result.exceptions.add(0, exception)
    }
}

def filterStackTraces(TestResult result) {
    for (Throwable throwable : result.getExceptions()) {
        filterStackTrace(throwable)
    }
}

// It would be nice to do this in a non-destructive way...
def filterStackTrace(Throwable exception) {
    if (!project.hasProperty('print_full_stacktraces')) {
        def elements = []
        def skipped = []
        for (StackTraceElement element : exception.getStackTrace()) {
            if (element.toString().contains("com.android.tools.r8")) {
                elements.addAll(skipped)
                elements.add(element)
                skipped.clear()
            } else {
                skipped.add(element)
            }
        }
        exception.setStackTrace(elements as StackTraceElement[])
    }
}

def printAllStackTracesToFile(List<Throwable> exceptions, File out) {
    new PrintStream(new FileOutputStream(out)).withCloseable {printer ->
        exceptions.forEach { it.printStackTrace(printer) }
    }
}

static def escapeHtml(String string) {
    return string.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
}

static def urlEncode(String string) {
    // Not sure why, but the + also needs to be converted to have working links.
    return URLEncoder.encode(string, "UTF-8").replace("+","%20")
}

def ensureDir(File dir) {
    dir.mkdirs()
    return dir
}

// Some of our test parameters have new lines :-( We really don't want test names to span lines.
static def sanitizedTestName(testDesc) {
    if (testDesc.getName().contains("\n")) {
        throw new RuntimeException("Unsupported use of newline in test name: '${testDesc.getName()}'")
    }
    return testDesc.getName()
}

static def desanitizedTestName(testName) {
    return testName
}

def getTestReportEntryDir(reportDir, testDesc) {
    return ensureDir(reportDir.toPath()
            .resolve(testDesc.getClassName())
            .resolve(sanitizedTestName(testDesc))
            .toFile())
}

def getTestReportEntryURL(reportDir, testDesc) {
    def classDir = urlEncode(testDesc.getClassName())
    def testDir = urlEncode(sanitizedTestName(testDesc))
    return "file://${reportDir}/${classDir}/${testDir}"
}

def getTestResultEntryOutputFile(reportDir, testDesc, fileName) {
    def dir = getTestReportEntryDir(reportDir, testDesc).toPath()
    return dir.resolve(fileName).toFile()
}

def withTestResultEntryWriter(reportDir, testDesc, fileName, append, fn) {
    def file = getTestResultEntryOutputFile(reportDir, testDesc, fileName)
    new FileWriter(file, append).withCloseable fn
}

static def getGitBranchName() {
    def out = new StringBuilder()
    def err = new StringBuilder()
    def proc = "git rev-parse --abbrev-ref HEAD".execute()
    proc.waitForProcessOutput(out, err)
    return out.toString().trim()
}

static def getFreshTestReportIndex(File reportDir) {
    def number = 0
    while (true) {
        def freshIndex = reportDir.toPath().resolve("index.${number++}.html").toFile()
        if (!freshIndex.exists()) {
            return freshIndex
        }
    }
}

def forEachTestReportAlreadyX(File reportDir, fileName, onTest) {
    def out = new StringBuilder()
    def err = new StringBuilder()
    def proc = "find . -name ${fileName}".execute([], reportDir)
    proc.waitForProcessOutput(out, err)
    def outString = out.toString()
    outString.eachLine {
        // Lines are of the form: ./<class>/<name>/FAILURE
        def clazz = null
        def name = null
        try {
            def trimmed = it.trim()
            def line = trimmed.substring(2)
            def sep = line.indexOf("/")
            clazz = line.substring(0, sep)
            name = line.substring(sep + 1, line.length() - fileName.length() - 1)
        } catch (Exception e) {
            logger.lifecycle("WARNING: failed attempt to read test description from: '${it}'")
            return
        }
        onTest(clazz, desanitizedTestName(name))
    }
    return !outString.trim().isEmpty()
}

def forEachTestReportAlreadyFailing(File reportDir, onFailureTest) {
    return forEachTestReportAlreadyX(reportDir, TestResult.ResultType.FAILURE.name(), onFailureTest)
}

def forEachTestReportAlreadyPassing(File reportDir, onSucceededTest) {
    return forEachTestReportAlreadyX(reportDir, TestResult.ResultType.SUCCESS.name(), onSucceededTest)
}

def forEachTestReportAlreadySkipped(File reportDir, onSucceededTest) {
    return forEachTestReportAlreadyX(reportDir, TestResult.ResultType.SKIPPED.name(), onSucceededTest)
}

def setUpTestingState(Test task) {
    // Hide all test events from the console, they are written to the report.
    task.testLogging { events = [] }

    def branch = project.hasProperty('testing-state-name')
        ? project.getProperty('testing-state-name')
        : getGitBranchName()
    def reportDir = file("${buildDir}/test-state/${branch}")
    def index = reportDir.toPath().resolve("index.html").toFile()
    def resetState = project.hasProperty('reset-testing-state')
    def reportDirExists = reportDir.exists()
    def resuming = !resetState && reportDirExists

    def hasFailingTests = false;
    if (resuming) {
        // Test filtering happens before the test execution is initiated so compute it here.
        // If there are still failing tests in the report, include only those.
        hasFailingTests = forEachTestReportAlreadyFailing(reportDir, {
            clazz, name -> task.filter.includeTestsMatching("$clazz.$name")
        })
        // Otherwise exclude all of the test already marked as succeeding.
        if (!hasFailingTests) {
            // Also allow the test to overall succeed if there are no remaining tests that match,
            // which is natural if the state already succeeded in full.
            task.filter.failOnNoMatchingTests = false
            forEachTestReportAlreadyPassing(reportDir, {
                clazz, name -> task.filter.excludeTestsMatching("$clazz.$name")
            })
            forEachTestReportAlreadySkipped(reportDir, {
                clazz, name -> task.filter.excludeTestsMatching("$clazz.$name")
            })
        }
    }

    task.beforeSuite { desc ->
        if (!desc.parent) {
            def parentReport = null
            if (resetState && reportDirExists) {
                delete reportDir
            }
            if (resuming) {
                if (index.exists()) {
                    parentReport = getFreshTestReportIndex(reportDir)
                    index.renameTo(parentReport)
                }
            } else {
                reportDir.mkdirs()
            }
            def runPrefix = resuming ? "Resuming" : "Starting"
            def title =  "${runPrefix} @ ${branch}"
            // Print a console link to the test report for easy access.
            println "${runPrefix} test, report written to:"
            println "  file://${index}"
            // Print the new index content.
            index << "<html><head><title>${title}</title>"
            index << "<style> * { font-family: monospace; }</style>"
            index << "<meta http-equiv='refresh' content='10' />"
            index << "</head><body><h1>${title}</h1>"
            index << "<p>Run on: ${new Date()}</p>"
            index << "<p>Git branch: ${branch}</p>"
            if (parentReport != null) {
                index << "<p><a href=\"file://${parentReport}\">Previous result index</a></p>"
            }
            index << "<p><a href=\"file://${index}\">Most recent result index</a></p>"
            index << "<p><a href=\"file://${reportDir}\">Test directories</a></p>"
            index << "<h2>Failing tests (refreshing automatically every 10 seconds)</h2><ul>"
        }
    }

    task.afterSuite { desc, result ->
        if (!desc.parent) {
            // Update the final test results in the index.
            index << "</ul>"
            if (result.resultType == TestResult.ResultType.SUCCESS) {
                if (hasFailingTests) {
                    index << "<h2>Rerun of failed tests now pass!</h2>"
                    index << "<h2>Rerun again to continue with outstanding tests!</h2>"
                } else {
                    index << "<h2 style=\"background-color:#62D856\">GREEN BAR == YOU ROCK!</h2>"
                }
            } else if (result.resultType == TestResult.ResultType.FAILURE) {
                index << "<h2 style=\"background-color:#6D130A\">Some tests failed: ${result.resultType.name()}</h2><ul>"
            } else {
                index << "<h2>Tests finished: ${result.resultType.name()}</h2><ul>"
            }
            index << "<li>Number of tests: ${result.testCount}"
            index << "<li>Failing tests: ${result.failedTestCount}"
            index << "<li>Successful tests: ${result.successfulTestCount}"
            index << "<li>Skipped tests: ${result.skippedTestCount}"
            index << "</ul></body></html>"
        }
    }

    // Events to stdout/err are appended to the files in the test directories.
    task.onOutput { desc, event ->
        withTestResultEntryWriter(reportDir, desc, event.getDestination().name(), true, {
            it.append(event.getMessage())
        })
    }

    task.beforeTest { desc ->
        // Remove any stale output files before running the test.
        for (def destType : TestOutputEvent.Destination.values()) {
            def destFile = getTestResultEntryOutputFile(reportDir, desc, destType.name())
            if (destFile.exists()) {
                delete destFile
            }
        }
    }

    task.afterTest { desc, result ->
        if (result.getTestCount() != 1) {
            throw new IllegalStateException("Unexpected test with more than one result: ${desc}")
        }
        // Clear any previous result files.
        for (def resultType : TestResult.ResultType.values()) {
            delete getTestResultEntryOutputFile(reportDir, desc, resultType.name())
        }
        // Emit the result type status in a file of the same name: SUCCESS, FAILURE or SKIPPED.
        withTestResultEntryWriter(reportDir, desc, result.getResultType().name(), false, {
            it.append(result.getResultType().name())
        })
        // Emit the test time.
        withTestResultEntryWriter(reportDir, desc, "time", false, {
            it.append("${result.getEndTime() - result.getStartTime()}")
        })
        // For failed tests, update the index and emit stack trace information.
        if (result.resultType == TestResult.ResultType.FAILURE) {
            def title = escapeHtml("${desc.className}.${desc.name}")
            def link = getTestReportEntryURL(reportDir, desc)
            index << "<li><a href=\"${link}\">${title}</a></li>"
            if (!result.exceptions.isEmpty()) {
                printAllStackTracesToFile(
                        result.exceptions,
                        getTestResultEntryOutputFile(
                                reportDir,
                                desc,
                                "exceptions-raw.txt"))
                filterStackTraces(result)
                printAllStackTracesToFile(
                        result.exceptions,
                        getTestResultEntryOutputFile(
                                reportDir,
                                desc,
                                "exceptions-filtered.txt"))
                if (shouldRetrace()) {
                    withTestResultEntryWriter(reportDir, desc, "exceptions-retraced.txt", false, { writer ->
                        result.exceptions.forEach { writer.append(retrace(it)) }
                    })
                }
            }
        }
    }
}

def testTimes = [:]
def numberOfTestTimesToPrint = 100

test { task ->

    dependsOn sourceSets.keepanno.output
    // R8.jar is required for running bootstrap tests.
    dependsOn r8

    def useTestingState = project.hasProperty('testing-state')
    if (useTestingState) {
        setUpTestingState(task)
    }

    if (project.hasProperty('generate_golden_files_to')) {
        systemProperty 'generate_golden_files_to', project.property('generate_golden_files_to')
        assert project.hasProperty('HEAD_sha1')
        systemProperty 'test_git_HEAD_sha1', project.property('HEAD_sha1')
    }

    if (project.hasProperty('use_golden_files_in')) {
        systemProperty 'use_golden_files_in', project.property('use_golden_files_in')
        assert project.hasProperty('HEAD_sha1')
        systemProperty 'test_git_HEAD_sha1', project.property('HEAD_sha1')
    }

    if (project.hasProperty('kotlin_compiler_dev')) {
        systemProperty 'com.android.tools.r8.kotlincompilerdev', '1';
    }

    if (project.hasProperty('kotlin_compiler_old')) {
        systemProperty 'com.android.tools.r8.kotlincompilerold', '1';
    }

    if (!useTestingState) {
        testLogging.exceptionFormat = 'full'
        if (project.hasProperty('print_test_stdout')) {
            testLogging.showStandardStreams = true
        }
    }
    if (project.hasProperty('dex_vm') && project.property('dex_vm') != 'default') {
        println "NOTE: Running with non default vm: " + project.property('dex_vm')
        systemProperty 'dex_vm', project.property('dex_vm')
    }

    // Forward runtime configurations for test parameters.
    if (project.hasProperty('runtimes')) {
        println "NOTE: Running with runtimes: " + project.property('runtimes')
        systemProperty 'runtimes', project.property('runtimes')
    }

    if (project.hasProperty('art_profile_rewriting_completeness_check')) {
        String key = 'com.android.tools.r8.artprofilerewritingcompletenesscheck'
        String value = project.property('art_profile_rewriting_completeness_check')
        systemProperty key, value
    }

    if (project.hasProperty('slow_tests')) {
        systemProperty 'slow_tests', project.property('slow_tests')
    }


    if (project.hasProperty('desugar_jdk_json_dir')) {
        systemProperty 'desugar_jdk_json_dir', project.property('desugar_jdk_json_dir')
    }
    if (project.hasProperty('desugar_jdk_libs')) {
        systemProperty 'desugar_jdk_libs', project.property('desugar_jdk_libs')
    }

    if (!useTestingState) {
        if (project.hasProperty('print_times') || project.hasProperty('one_line_per_test')) {
            afterTest { desc, result ->
                def executionTime = (result.endTime - result.startTime) / 1000
                testTimes["${desc.name} [${desc.className}]"] = executionTime
            }
            afterSuite { desc, result ->
                // parent is null if all tests are done.
                if (desc.parent == null) {
                    def sortedTimes = testTimes.sort({ e1, e2 -> e2.value <=> e1.value })
                    sortedTimes.eachWithIndex { key, value, i ->
                        println "$key: $value"
                    }
                }
            }
        }

        if (project.hasProperty('one_line_per_test')) {
            beforeTest { desc ->
                println "Start executing test ${desc.name} [${desc.className}]"
            }

            afterTest { desc, result ->
                if (result.resultType == TestResult.ResultType.FAILURE) {
                    printStackTrace(result)
                }
                if (project.hasProperty('update_test_timestamp')) {
                    file(project.getProperty('update_test_timestamp')).text = new Date().getTime()
                }
                println "Done executing test ${desc.name} [${desc.className}] with result: ${result.resultType}"
            }
        } else {
            afterTest { desc, result ->
                if (result.resultType == TestResult.ResultType.FAILURE) {
                    printStackTrace(result)
                }
            }
        }
    }
    if (project.hasProperty('no_internal')) {
        exclude "com/android/tools/r8/internal/**"
    }
    if (project.hasProperty('only_internal')) {
        include "com/android/tools/r8/internal/**"
    }

    if (project.hasProperty('test_namespace')) {
        include "com/android/tools/r8/" + project.getProperty('test_namespace') + "/**"
    }

    if (project.hasProperty('tool') && project.property('tool') == 'd8') {
        // Don't run anything, deprecated
        println "Running with deprecated tool d8, not running any tests"
        include ""
    }
    if (project.hasProperty('no_arttests')) {
        exclude "com/android/tools/r8/art/**"
    }
    if (project.hasProperty('shard_count') ) {
      assert project.hasProperty('shard_number')
      int shard_count = project.getProperty('shard_count') as Integer
      int shard_number = project.getProperty('shard_number') as Integer
      assert shard_count < 65536
      assert shard_number < shard_count
      exclude {
        entry ->
          // Don't leave out directories. Leaving out a directory means all entries below.
          if (entry.file.isDirectory()) {
           return false
          }
          def first4 = entry.getRelativePath().toString().md5().substring(0, 4)
          int hash = Integer.parseInt(first4, 16)
          return hash % shard_count != shard_number
      }
    }
    if (project.hasProperty('test_dir')) {
        systemProperty 'test_dir', project.property('test_dir')
    }
    if (project.hasProperty('command_cache_dir')) {
        systemProperty 'command_cache_dir', project.property('command_cache_dir')
    }
    if (project.hasProperty('r8lib')) {
        dependsOn configureTestForR8Lib
        // R8lib should be used instead of the main output and all the tests in
        // r8 should be mapped and exists in r8LibTestPath.
        classpath = sourceSets.test.runtimeClasspath.filter {
            !it.getAbsolutePath().contains("/build/")
        }
        classpath += files([r8LibPath, r8LibTestPath])
        testClassesDirs = files(r8LibTestPath)
    }
    if (OperatingSystem.current().isLinux()
            || OperatingSystem.current().isMacOsX()
            || OperatingSystem.current().isWindows()) {
        if (OperatingSystem.current().isMacOsX()) {
            logger.lifecycle("WARNING: Testing in only partially supported on Mac OS. " +
                "Art only runs on Linux and tests requiring Art runs in a Docker container, which must be present. " +
                "See tools/docker/README.md for details.")
        }
        if (OperatingSystem.current().isWindows()) {
            logger.lifecycle("WARNING: Testing in only partially supported on Windows. " +
                    "Art only runs on Linux and tests requiring Art will be skipped")
        }
        dependsOn downloadDeps
        dependsOn buildExamples
        dependsOn buildPreNJdwpTestsJar
    } else {
        logger.lifecycle("WARNING: Testing in not supported on your platform. Testing is only fully supported on " +
            "Linux and partially supported on Mac OS and Windows. Art does not run on other platforms.")
    }
}


task javadocD8(type: Javadoc) {
  title "D8 API"
  classpath = sourceSets.main.compileClasspath
  source = sourceSets.main.allJava
  include '**/com/android/tools/r8/ArchiveClassFileProvider.java'
  include '**/com/android/tools/r8/ArchiveProgramResourceProvider.java'
  include '**/com/android/tools/r8/BaseCommand.java'
  include '**/com/android/tools/r8/BaseCompilerCommand.java'
  include '**/com/android/tools/r8/ClassFileResourceProvider.java'
  include '**/com/android/tools/r8/CompilationFailedException.java'
  include '**/com/android/tools/r8/CompilationMode.java'
  include '**/com/android/tools/r8/D8.java'
  include '**/com/android/tools/r8/D8Command.java'
  include '**/com/android/tools/r8/DexIndexedConsumer.java'
  include '**/com/android/tools/r8/DexFilePerClassFileConsumer.java'
  include '**/com/android/tools/r8/Diagnostic.java'
  include '**/com/android/tools/r8/DiagnosticsHandler.java'
  include '**/com/android/tools/r8/DirectoryClassFileProvider.java'
  include '**/com/android/tools/r8/OutputMode.java'
  include '**/com/android/tools/r8/ProgramConsumer.java'
  include '**/com/android/tools/r8/ProgramResource.java'
  include '**/com/android/tools/r8/ProgramResourceProvider.java'
  include '**/com/android/tools/r8/Resource.java'
  include '**/com/android/tools/r8/ResourceException.java'
  include '**/com/android/tools/r8/StringConsumer.java'
  include '**/com/android/tools/r8/StringResource.java'
  include '**/com/android/tools/r8/Version.java'
  include '**/com/android/tools/r8/origin/*.java'
}

task javadocR8(type: Javadoc) {
  title "R8 API"
  classpath = sourceSets.main.compileClasspath
  source = sourceSets.main.allJava
  include '**/com/android/tools/r8/ArchiveClassFileProvider.java'
  include '**/com/android/tools/r8/ArchiveProgramResourceProvider.java'
  include '**/com/android/tools/r8/BaseCommand.java'
  include '**/com/android/tools/r8/BaseCompilerCommand.java'
  include '**/com/android/tools/r8/ClassFileConsumer.java'
  include '**/com/android/tools/r8/ClassFileResourceProvider.java'
  include '**/com/android/tools/r8/CompilationFailedException.java'
  include '**/com/android/tools/r8/CompilationMode.java'
  include '**/com/android/tools/r8/R8.java'
  include '**/com/android/tools/r8/R8Command.java'
  include '**/com/android/tools/r8/DexIndexedConsumer.java'
  include '**/com/android/tools/r8/Diagnostic.java'
  include '**/com/android/tools/r8/DiagnosticsHandler.java'
  include '**/com/android/tools/r8/DirectoryClassFileProvider.java'
  include '**/com/android/tools/r8/OutputMode.java'
  include '**/com/android/tools/r8/ProgramConsumer.java'
  include '**/com/android/tools/r8/ProgramResource.java'
  include '**/com/android/tools/r8/ProgramResourceProvider.java'
  include '**/com/android/tools/r8/Resource.java'
  include '**/com/android/tools/r8/ResourceException.java'
  include '**/com/android/tools/r8/StringConsumer.java'
  include '**/com/android/tools/r8/StringResource.java'
  include '**/com/android/tools/r8/Version.java'
  include '**/com/android/tools/r8/origin/*.java'
}

task copyMavenDeps(type: Copy) {
    from configurations.compile into "$buildDir/deps"
    from configurations.compileClasspath into "$buildDir/deps"
    from configurations.testCompile into "$buildDir/deps"
}

task printMavenDeps {
    // Only actually print to stdout when we are updating.
    if (project.hasProperty('updatemavendeps')) {
        for (Configuration config : configurations) {
            if (!config.isCanBeResolved()) {
                continue
            }
            def componentIds = config.incoming.resolutionResult.allDependencies.collect {
                it.selected.id
            }
            def result = dependencies.createArtifactResolutionQuery()
                .forComponents(componentIds)
                .withArtifacts(MavenModule, MavenPomArtifact)
                .execute()
            for (component in result.resolvedComponents) {
                component.getArtifacts(MavenPomArtifact).each {
                    println "POM: ${it.file} ${component.id}"
                }
            }
            config.each {
                println "JAR: ${it}"
            }
        }
    }
}

allprojects {
  tasks.withType(Exec) {
    doFirst {
      println commandLine.join(' ')
    }
  }
}
