import de.undercouch.gradle.tasks.download.Download

plugins {
    // https://plugins.gradle.org/plugin/com.github.johnrengelman.shadow (v5 requires Gradle 5)
    id 'com.github.johnrengelman.shadow' version '6.1.0'
    // https://plugins.gradle.org/plugin/de.undercouch.download
    id "de.undercouch.download" version "4.1.1"
    id 'java'
    // https://github.com/tbroyer/gradle-errorprone-plugin
    id "net.ltgt.errorprone" version "2.0.1"
    // https://plugins.gradle.org/plugin/org.ajoberstar.grgit
    id 'org.ajoberstar.grgit' version '4.1.0' apply false
    // https://github.com/n0mer/gradle-git-properties ; target is: generateGitProperties
    id "com.gorylenko.gradle-git-properties" version "2.3.1"
}
apply plugin: "de.undercouch.download"

import org.ajoberstar.grgit.Grgit

repositories {
    jcenter()
    mavenCentral()
}

gitProperties {
    // logically belongs in framework, but only checker resources are copied to .jar file
    gitPropertiesResourceDir = file("${project.rootDir}/checker/src/main/resources")
}

ext {
    release = false

    // On a Java 8 JVM, use error-prone javac and source/target 8.
    // On a Java 9+ JVM, use the host javac, default source/target, and required module flags.
    isJava8 = JavaVersion.current() == JavaVersion.VERSION_1_8

    errorproneJavacVersion = '9+181-r4173-1'

    parentDir = file("${rootDir}/../").absolutePath

    annotationTools = "${parentDir}/annotation-tools"
    afu = "${annotationTools}/annotation-file-utilities"

    stubparser = "${parentDir}/stubparser"
    stubparserJar = "${stubparser}/javaparser-core/target/stubparser-3.20.2.1.jar"

    jtregHome = "${parentDir}/jtreg"
    formatScriptsHome = "${project(':checker').projectDir}/bin-devel/.run-google-java-format"
    plumeScriptsHome = "${project(':checker').projectDir}/bin-devel/.plume-scripts"
    htmlToolsHome = "${project(':checker').projectDir}/bin-devel/.html-tools"

    javadocMemberLevel = JavadocMemberLevel.PROTECTED

    // The local git repository, typically in the .git directory, but not for worktrees.
    // This value is always overwritten, but Gradle needs the variable to be initialized.
    localRepo = ".git"
}
// Keep in sync with check in org.checkerframework.framework.source.SourceChecker.init
// and with text in #installation
switch (JavaVersion.current()) {
    case JavaVersion.VERSION_1_9:
    case JavaVersion.VERSION_1_10:
    case JavaVersion.VERSION_12:
        logger.warn("The Checker Framework has only been tested with JDK 8 and 11." +
                " Found version " + JavaVersion.current().majorVersion);
        break;
    case JavaVersion.VERSION_1_8:
    case JavaVersion.VERSION_11:
        break; // Supported versions
    default:
        throw new GradleException("Build the Checker Framework with JDK 8 or JDK 11." +
                " Found version " + JavaVersion.current().majorVersion);
}

task setLocalRepo(type:Exec) {
    commandLine 'git', 'worktree', 'list'
    standardOutput = new ByteArrayOutputStream()
    doLast {
       String worktreeList = standardOutput.toString()
       localRepo = worktreeList.substring(0, worktreeList.indexOf(" ")) + "/.git"
    }
}

// No group so it does not show up in the output of `gradlew tasks`
task installGitHooks(type: Copy, dependsOn: 'setLocalRepo') {
    description 'Copies git hooks to .git directory'
    from files("checker/bin-devel/git.post-merge", "checker/bin-devel/git.pre-commit")
    rename('git\\.(.*)', '$1')
    into localRepo + "/hooks"
}

allprojects {
    apply plugin: 'java'
    apply plugin: 'com.github.johnrengelman.shadow'
    apply plugin: "de.undercouch.download"
    apply plugin: 'net.ltgt.errorprone'

    group 'org.checkerframework'
    // Increment the minor version (second number) rather than just the patch
    // level (third number) if:
    //   * any new checkers have been added, or
    //   * backward-incompatible changes have been made to APIs or elsewhere.
    version '3.13.1-SNAPSHOT'

    repositories {
        mavenCentral()
    }

    configurations {
        javacJar

        // Holds the combined classpath of all subprojects including the subprojects themselves.
        allProjects

        // Exclude checker-qual dependency added by Error Prone to avoid a circular dependency.
        annotationProcessor.exclude group:'org.checkerframework', module:'checker-qual'
    }

    configurations {
        checkerFatJar
    }
    dependencies {
        if (isJava8) {
            javacJar group: 'com.google.errorprone', name: 'javac', version: "$errorproneJavacVersion"
        }

        errorproneJavac("com.google.errorprone:javac:$errorproneJavacVersion")

        allProjects subprojects
        checkerFatJar project(path: ':checker', configuration: 'shadow')
    }


    // After all the tasks have been created, modify some of them.
    afterEvaluate {
        // Add the fat checker.jar to the classpath of every Javadoc task. This allows Javadoc in
        // any module to reference classes in any other module.
        // Also, build and use ManualTaglet as a taglet.
        tasks.withType(Javadoc) {
            def tagletVersion = isJava8 ? 'taglet' : 'tagletJdk11'

            dependsOn(':checker:shadowJar')
            dependsOn(":framework-test:${tagletVersion}Classes")
            doFirst {
                options.encoding = 'UTF-8'
                if (!name.equals("javadocDoclintAll")) {
                    options.memberLevel = javadocMemberLevel
                }
                classpath += rootProject.configurations.getByName('checkerFatJar').asFileTree
                if (isJava8) {
                    classpath += configurations.javacJar
                }
                options.taglets 'org.checkerframework.taglet.ManualTaglet'
                options.tagletPath(project(':framework-test').sourceSets."${tagletVersion}".output.classesDirs.getFiles() as File[])

                // We want to link to Java 9 documentation of the compiler classes since we use Java 9
                // versions of those classes and Java 8 for everything else.  Because the compiler classes are not
                // a part of the main documentation of Java 8, javadoc links to the Java 9 versions.
                // TODO, this creates broken links to the com.sun.tools.javac package.
                options.links = ['https://docs.oracle.com/javase/8/docs/api/', 'https://docs.oracle.com/javase/9/docs/api/']
                // This file is looked for by Javadoc.
                file("${destinationDir}/resources/fonts/").mkdirs()
                ant.touch(file: "${destinationDir}/resources/fonts/dejavu.css")
                options.addStringOption('source', '8')
                // "-Xwerror" requires Javadoc everywhere.  Currently, CI jobs require Javadoc only
                // on changed lines.  Enable -Xwerror in the future when all Javadoc exists.
                // options.addBooleanOption('Xwerror', true)
                options.addStringOption('Xmaxwarns', '99999')
            }
        }

        // Add standard javac options
        tasks.withType(JavaCompile) { compilationTask ->
            dependsOn(':installGitHooks')
            // Put source files in deterministic order, for debugging.
            compilationTask.source = compilationTask.source.sort()
            sourceCompatibility = 8
            targetCompatibility = 8
            // Because the target is 8, all of the public compiler classes are accessible, so
            // --add-exports are not required, (nor are they allowed with target 8). See
            // https://openjdk.java.net/jeps/247 for details on compiling for older versions.

            // When sourceCompatibilty is changed to 11, then the following will be required.
            // options.compilerArgs += [
            // "--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
            // "--add-exports", "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
            // "--add-exports", "jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED",
            // "--add-exports", "jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED",
            // "--add-exports", "jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
            // "--add-exports", "jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED",
            // "--add-exports", "jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED",
            // "--add-exports", "jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
            // "--add-exports", "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
            // ]
            // This is equivalent to writing "exports jdk.compiler/... to ALL-UNNAMED" in the
            // module-info.java of jdk.compiler, so corresponding --add-opens are only required for
            // reflective access to private members.
            //
            // From https://openjdk.java.net/jeps/261, Section titled: "Breaking encapsulation"
            // "The effect of each instance [of --add-exports] is to add a qualified export of the
            // named package from the source module to the target module. This is, essentially, a
            // command-line form of an exports clause in a module declaration[...].
            // [...]
            // The --add-exports option enables access to the public types of a specified package.
            // It is sometimes necessary to go further and enable access to all non-public elements
            // via the setAccessible method of the core reflection API. The --add-opens option can
            // be used, at run time, to do this."

            options.failOnError = true
            options.deprecation = true
            options.compilerArgs += [
                    '-g',
                    '-Werror',
                    // -options: To not get a warning about missing bootstrap classpath for Java 8 (once we use Java 9).
                    // -fallthrough: Don't check fallthroughs.  Instead, use Error Prone.  Its
                    // warnings are suppressible with a "// fall through" comment.
                    "-Xlint:-options,-fallthrough",
                    "-Xlint",
            ]

            options.encoding = 'UTF-8'
            options.fork = true
            if (isJava8) {
                options.forkOptions.jvmArgs += ["-Xbootclasspath/p:${configurations.javacJar.asPath}".toString()]
            }

            // Error prone depends on checker-qual.jar, so don't run it on that project to avoid a circular dependency.
            // TODO: enable Error Prone on test classes.
            if (compilationTask.name.equals('compileJava') && !project.name.startsWith('checker-qual')) {
                // Error Prone must be available in the annotation processor path
                options.annotationProcessorPath = configurations.errorprone
                // Enable Error Prone
                options.errorprone.enabled = true
                options.errorprone.disableWarningsInGeneratedCode = true
                options.errorprone.errorproneArgs = [
                        // Many compiler classes are interned.
                        '-Xep:ReferenceEquality:OFF',
                        // These might be worth fixing.
                        '-Xep:DefaultCharset:OFF',
                        // Not useful to suggest Splitter; maybe clean up.
                        '-Xep:StringSplitter:OFF',
                        // Too broad, rejects seemingly-correct code.
                        '-Xep:EqualsGetClass:OFF',
                        // Not a real problem
                        '-Xep:MixedMutabilityReturnType:OFF',
                        // Don't want to add a dependency to ErrorProne.
                        '-Xep:AnnotateFormatMethod:OFF',
                        // Warns for every use of "@checker_framework.manual"
                        '-Xep:InvalidBlockTag:OFF',
                        // Recommends writing @InlineMe which is an Error-Prone-specific annotation
                        '-Xep:InlineMeSuggester:OFF',
                        // -Werror halts the build if Error Prone issues a warning, which ensures that
                        // the errors get fixed.  On the downside, Error Prone (or maybe the compiler?)
                        // stops as soon as it issues one warning, rather than outputting them all.
                        // https://github.com/google/error-prone/issues/436
                        '-Werror',
                ]
            } else {
                options.errorprone.enabled = false
            }
        }
    }
}

task cloneAndBuildDependencies(type: Exec, group: 'Build') {
    description 'Clones (or updates) and builds all dependencies'
    executable 'checker/bin-devel/build.sh'
}

task maybeCloneAndBuildDependencies() {
    // No group so it does not show up in the output of `gradlew tasks`
    description 'Clones (or updates) and builds all dependencies if they are not present.'
    onlyIf {
        !file(stubparserJar).exists()
        // The jdk repository is cloned via the copyAndMinimizeAnnotatedJdkFiles task that is run if
        // the repository does not exist when building checker.jar.
    }

    doFirst {
        if (file(stubparser).exists()) {
            exec {
                workingDir stubparser
                executable 'git'
                args = ['pull', '-q']
                ignoreExitValue = true
            }
            exec {
                workingDir stubparser
                executable "${stubparser}/.travis-build-without-test.sh"
            }
        } else {
            executable 'checker/bin-devel/build.sh'
        }
    }
    doLast {
        if (!file(stubparserJar).exists()) {
            exec {
                workingDir ${stubparser}/javaparser-core/target
                executable 'ls'
                ignoreExitValue = true
            }
            throw new RuntimeException("Can't find stubparser jar: " + stubparserJar)
        }
    }
}

task version(group: 'Documentation') {
    description 'Print Checker Framework version'
    doLast {
        println version
    }
}

/**
 * Creates a task that runs the checker on the main source set of each subproject. The task is named
 * "check${taskName}", for example "checkPurity" or "checkNullness".
 *
 * @param projectName name of the project
 * @param taskName short name (often the checker name) to use as part of the task name
 * @param checker fully qualified name of the checker to run
 * @param args list of arguments to pass to the checker
 */
def createCheckTypeTask(projectName, taskName, checker, args = []) {
    project("${projectName}").tasks.create(name: "check${taskName}", type: JavaCompile, dependsOn: ':checker:shadowJar') {
        description "Run the ${taskName} Checker on the main sources."
        group 'Verification'
        // Always run the task.
        outputs.upToDateWhen { false }
        source = project("${projectName}").sourceSets.main.java
        classpath = files(project("${projectName}").compileJava.classpath,project(':checker-qual').sourceSets.main.output)
        destinationDir = file("${buildDir}")

        options.annotationProcessorPath = files(project(':checker').tasks.shadowJar.archivePath)
        options.compilerArgs += [
                '-processor', "${checker}",
                '-proc:only',
                '-Xlint:-processing',
                '-Xmaxerrs', '10000',
                '-Xmaxwarns', '10000',
                '-ArequirePrefixInWarningSuppressions',
                '-AwarnUnneededSuppressions',
        ]
        options.compilerArgs += args
        options.forkOptions.jvmArgs += ["-Xmx2g"]

        if (isJava8) {
            options.compilerArgs += [
                "-source",
                "8",
                "-target",
                "8"
                ]
        } else {
            options.fork = true
            options.forkOptions.jvmArgs += [
                "--add-opens", "jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED",
                ]
       }
    }
}

/**
 * Returns a list of all the Java files that should be formatted for the given project. These are:
 *
 * All java files in the main sourceSet.
 * All java files in the tests directory that compile.
 *
 * @param projectName name of the project to format
 * @return a list of all Java files that should be formatted for projectName
 */
List<String> getJavaFilesToFormat(projectName) {
    List<File> javaFiles = new ArrayList<>();
    project(':' + projectName).sourceSets.forEach { set ->
        javaFiles.addAll(set.java.files)
    }

    // Collect all java files in tests directory
    fileTree("${project(projectName).projectDir}/tests").visit { details ->
        // If you change this, also change checker/bin-devel/git.pre-commit
        if (!details.path.contains("nullness-javac-errors")
                && !details.path.contains("returnsreceiverdelomboked")
                && !details.path.contains("build")
                && details.name.endsWith('.java')) {
            javaFiles.add(details.file)
        }
    }

    // Collect all java files in jtreg directory
    fileTree("${project(projectName).projectDir}/jtreg").visit { details ->
        if (!details.path.contains("nullness-javac-errors") && details.name.endsWith('.java')) {
            javaFiles.add(details.file)
        }
    }

    // Collect all java files in jtregJdk11 directory
    fileTree("${project(projectName).projectDir}/jtregJdk11").visit { details ->
        if (!details.path.contains("nullness-javac-errors") && details.name.endsWith('.java')) {
            javaFiles.add(details.file)
        }
    }

    List<String> args = new ArrayList<>(javaFiles.size());
    for (File f : javaFiles) {
        args += project(projectName).relativePath(f)
    }
    return args
}

task htmlValidate(type: Exec, group: 'Format') {
    description 'Validate that HTML files are well-formed'
    executable 'html5validator'
    args = [
            "--ignore",
            "/api/",
            "/build/",
            "/docs/manual/manual.html",
            "/checker/jdk/nullness/src/java/lang/ref/package.html"
    ]
}


// `gradle allJavadoc` builds the Javadoc for all modules in `docs/api`.
//   This is what is published to checkerframework.org.
// `gradle javadoc` builds the Javadoc for each sub-project in <subproject>/build/docs/javadoc/ .
//   It's needed to create the Javadoc jars that we release in Maven Central.
// To make javadoc for only one subproject, run `./gradlew javadoc`
//   in the subproject or `./gradlew :checker:javadoc` at the top level.
task allJavadoc(type: Javadoc, group: 'Documentation') {
    description = 'Generates API documentation that includes all the modules.'
    dependsOn(':checker:shadowJar', 'getPlumeScripts', 'getHtmlTools')
    destinationDir = file("${rootDir}/docs/api")
    source(project(':checker-util').sourceSets.main.allJava, project(':checker-qual').sourceSets.main.allJava, project(':checker').sourceSets.main.allJava, project(':framework').sourceSets.main.allJava,
            project(':dataflow').sourceSets.main.allJava, project(':javacutil').sourceSets.main.allJava)

    classpath = configurations.allProjects
    if (isJava8) {
        classpath += configurations.javacJar
    }
    doLast {
        exec {
            // Javadoc for to com.sun.tools.java.* is not publicly available, so these links are broken.
            // This command removes those links.
            workingDir "${rootDir}/docs/api"
            executable "${plumeScriptsHome}/preplace"
            args += ['<a href="https://docs.oracle.com/javase/9/docs/api/com/sun/tools/javac/.*?>(.*?)</a>', '\\1']
        }
        copy {
            from 'docs/logo/Checkmark/CFCheckmark_favicon.png'
            rename('CFCheckmark_favicon.png', 'favicon-checkerframework.png')
            into "${rootDir}/docs/api"
        }
        exec {
            workingDir "${rootDir}/docs/api"
            executable "${htmlToolsHome}/html-add-favicon"
            args += ['.', 'favicon-checkerframework.png']
        }
    }
}

// See documentation for allJavadoc task.
javadoc.dependsOn(allJavadoc)

configurations {
    requireJavadoc
}
dependencies {
    requireJavadoc "org.plumelib:require-javadoc:1.0.2"
}
task requireJavadoc(type: JavaExec, group: 'Documentation') {
    description = 'Ensures that Javadoc documentation exists in source code.'
    main = "org.plumelib.javadoc.RequireJavadoc"
    classpath = configurations.requireJavadoc
    args "checker/src/main/java", "dataflow/src/main/java", "framework-test/src/main/java", "framework/src/main/java", "javacutil/src/main/java"
}


/**
 * Creates a task named taskName that runs javadoc with the -Xdoclint:all option.
 *
 * @param taskName the name of the task to create
 * @param taskDescription description of the task
 * @param memberLevel the JavadocMemberLevel to use
 * @return the new task
 */
def createJavadocTask(taskName, taskDescription, memberLevel) {
    tasks.create(name: taskName, type: Javadoc) {
        description = taskDescription
        destinationDir = file("${rootDir}/docs/tmpapi")
        destinationDir.mkdirs()
        subprojects.forEach {
            if (!it.name.startsWith("checker-qual-android")) {
                source += it.sourceSets.main.allJava
            }
        }

        classpath = configurations.allProjects

        destinationDir.deleteDir()
        options.memberLevel = memberLevel
        options.addBooleanOption('Xdoclint:all', true)
        options.addStringOption('Xmaxwarns', '99999')

        // options.addStringOption('skip', 'ClassNotToCheck|OtherClass')
    }
}

createJavadocTask('javadocDoclintAll', 'Runs javadoc with -Xdoclint:all option.', JavadocMemberLevel.PRIVATE)

task manual(group: 'Documentation') {
    description 'Build the manual'
    doLast {
        exec {
            commandLine "make", "-C", "docs/manual", "all"
        }
    }
}

// No group so it does not show up in the output of `gradlew tasks`
task downloadJtreg(type: Download) {
    description "Downloads and unpacks jtreg."
    onlyIf { !(new File("${jtregHome}/lib/jtreg.jar").exists()) }
    // src 'https://ci.adoptopenjdk.net/view/Dependencies/job/jtreg/lastSuccessfulBuild/artifact/jtreg-4.2.0-tip.tar.gz'
    // If ci.adoptopenjdk.net is down, use this copy.
    src 'https://checkerframework.org/jtreg-4.2.0-tip.tar.gz'
    dest new File(buildDir, 'jtreg-4.2.0-tip.tar.gz')
    overwrite true
    retries 3
    doLast {
        copy {
            from tarTree(dest)
            into "${jtregHome}/.."
        }
        exec {
            commandLine('chmod',  '+x', "${jtregHome}/bin/jtdiff", "${jtregHome}/bin/jtreg")
        }
    }
}

// See alternate implementation getCodeFormatScriptsInGradle below.
// No group so it does not show up in the output of `gradlew tasks`
task getCodeFormatScripts() {
    description 'Obtain or update the run-google-java-format scripts'
    if (file(formatScriptsHome).exists()) {
        exec {
            workingDir formatScriptsHome
            executable 'git'
            args = ['pull', '-q']
            ignoreExitValue = true
        }
    } else {
        exec {
            workingDir "${formatScriptsHome}/../"
            executable 'git'
            args = ['clone', '-q', '--depth', '1', 'https://github.com/plume-lib/run-google-java-format.git', '.run-google-java-format']
        }
    }
}

// This implementation is preferable to the above because it does work in Gradle rather than in bash.
// However, it fails in the presence of worktrees: https://github.com/ajoberstar/grgit/issues/97 .
// No group so it does not show up in the output of `gradlew tasks`
task getCodeFormatScriptsInGradle {
  description "Obtain the run-google-java-format scripts"
  doLast {
    if (! new File(formatScriptsHome).exists()) {
      // There is no support for the --depth argument:
      // https://github.com/ajoberstar/grgit/issues/155   https://bugs.eclipse.org/bugs/show_bug.cgi?id=475615
      def rgjfGit = Grgit.clone(dir: formatScriptsHome, uri: 'https://github.com/plume-lib/run-google-java-format.git')
    } else {
      def rgjfGit = Grgit.open(dir: formatScriptsHome)
      rgjfGit.pull()
    }
  }
}

// No group so it does not show up in the output of `gradlew tasks`
task getPlumeScripts() {
    description 'Obtain or update plume-scripts'
    if (file(plumeScriptsHome).exists()) {
        exec {
            workingDir plumeScriptsHome
            executable 'git'
            args = ['pull', '-q']
            ignoreExitValue = true
        }
    } else {
        exec {
            workingDir "${plumeScriptsHome}/../"
            executable 'git'
            args = ['clone', '-q', '--depth', '1', 'https://github.com/plume-lib/plume-scripts.git', '.plume-scripts']
        }
    }
}

// No group so it does not show up in the output of `gradlew tasks`
task getHtmlTools() {
    description 'Obtain or update html-tools'
    if (file(htmlToolsHome).exists()) {
        exec {
            workingDir htmlToolsHome
            executable 'git'
            args = ['pull', '-q']
            ignoreExitValue = true
        }
    } else {
        exec {
            workingDir "${htmlToolsHome}/../"
            executable 'git'
            args = ['clone', '-q', '--depth', '1', 'https://github.com/plume-lib/html-tools.git', '.html-tools']
        }
    }
}

// No group so it does not show up in the output of `gradlew tasks`
task pythonIsInstalled(type: Exec) {
  description "Check that the python3 executable is installed."
  executable = "python3"
  args "--version"
}

task tags {
    group 'Emacs'
    description 'Create Emacs TAGS table'
    doLast {
        exec {
            commandLine "etags", "-i", "checker/TAGS", "-i", "checker-qual/TAGS", "-i", "checker-util/TAGS", "-i", "dataflow/TAGS", "-i", "framework/TAGS", "-i", "framework-test/TAGS", "-i", "javacutil/TAGS", "-i", "docs/manual/TAGS"
        }
        exec {
            commandLine "make", "-C", "docs/manual", "tags"
        }
    }
}

subprojects {
    configurations {
        errorprone
    }

    dependencies {
        // https://mvnrepository.com/artifact/com.google.errorprone/error_prone_core
        // If you update this:
        //  * Temporarily comment out "-Werror" elsewhere in this file
        //  * Repeatedly run `./gradlew clean compileJava` and fix all errors
        //  * Uncomment "-Werror"
        //  * Don't edit framework/build.gradle to use the same version number
        //    (it is updated when the annotated version of Guava is updated).
        errorprone group: 'com.google.errorprone', name: 'error_prone_core', version: '2.7.1'
    }

    task checkFormat(type: Exec, dependsOn: [getCodeFormatScripts, pythonIsInstalled], group: 'Format') {
        description 'Check whether the source code is properly formatted'
        // checker-qual-android project has no source, so skip
        onlyIf {!project.name.startsWith('checker-qual-android') }
        executable 'python3'

        doFirst {
            args += "${formatScriptsHome}/check-google-java-format.py"
            args += getJavaFilesToFormat(project.name)
        }
        ignoreExitValue = true
        doLast {
            if (execResult.exitValue != 0) {
                throw new RuntimeException('Found improper formatting, try running:  ./gradlew reformat"')
            }
        }
    }

    task reformat(type: Exec, dependsOn: [getCodeFormatScripts, pythonIsInstalled], group: 'Format') {
        description 'Format the Java source code'
        // checker-qual-android project has no source, so skip
        onlyIf {!project.name.startsWith('checker-qual-android') }
        executable 'python3'
        doFirst {
            args += "${formatScriptsHome}/run-google-java-format.py"
            args += getJavaFilesToFormat(project.name)
        }
    }

    shadowJar {
        // If you add an external dependency, then do the following:
        // 1. Before adding the dependency, run ./gradlew copyJarsToDist.
        // 2. Copy checker/dist/checker.jar elsewhere.
        // 3. Add the dependency, then run ./gradlew clean copyJarsToDist.
        // 4. Unzip both jars and compare the contents.
        // 5. Add relocate lines below for the packages.
        // 6. Do steps 3-5 until all new classes are in org/checkerframework/.

        // Relocate packages that might conflict with user's classpath.
        relocate 'org.apache', 'org.checkerframework.org.apache'
        relocate 'org.relaxng', 'org.checkerframework.org.relaxng'
        relocate 'org.plumelib', 'org.checkerframework.org.plumelib'
        relocate 'org.codehaus', 'org.checkerframework.org.codehaus'
        relocate 'org.objectweb.asm', 'org.checkerframework.org.objectweb.asm'
        relocate 'io.github.classgraph', 'org.checkerframework.io.github.classgraph'
        relocate 'nonapi.io.github.classgraph', 'org.checkerframework.nonapi.io.github.classgraph'
        // relocate 'sun', 'org.checkerframework.sun'
        relocate 'com.google', 'org.checkerframework.com.google'
        relocate 'plume', 'org.checkerframework.plume'
        exclude '**/module-info.class'

        doFirst {
            if (release) {
                // Only relocate JavaParser during a release:
                relocate 'com.github.javaparser', 'org.checkerframework.com.github.javaparser'
            }
        }
    }

    if (!project.name.startsWith('checker-qual-android')) {
        task tags(type: Exec) {
            description 'Create Emacs TAGS table'
            commandLine "bash", "-c", "find . \\( -name build \\) -prune -o -name '*.java' -print | sort-directory-order | xargs ctags -e -f TAGS"
        }
    }

    java {
        withJavadocJar()
        withSourcesJar()
    }

    // Things in this block reference definitions in the subproject that do not exist,
    // until the project is evaluated.
    afterEvaluate {
        // Adds manifest to all Jar files
        tasks.withType(Jar) {
            includeEmptyDirs = false
            if (archiveFileName.get().startsWith("checker-qual") || archiveFileName.get().startsWith("checker-util")) {
                metaInf {
                    from './LICENSE.txt'
                }
            } else {
                metaInf {
                    from "${rootDir}/LICENSE.txt"
                }
            }
            manifest {
                attributes("Implementation-Version": "${project.version}")
                attributes("Implementation-URL": "https://checkerframework.org")
                if (! archiveFileName.get().endsWith("source.jar")) {
                    attributes('Automatic-Module-Name': "org.checkerframework." + project.name.replaceAll('-', '.'))
                }
                if (archiveFileName.get().startsWith("checker-qual") || archiveFileName.get().startsWith("checker-util")) {
                    attributes("Bundle-License": "MIT")
                } else {
                    attributes("Bundle-License": "(GPL-2.0-only WITH Classpath-exception-2.0)")
                }
            }
        }

        // Add tasks to run various checkers on all the main source sets.
        // These pass and are run by typecheckTests.
        createCheckTypeTask(project.name, 'Formatter',
            'org.checkerframework.checker.formatter.FormatterChecker')
        createCheckTypeTask(project.name, 'Interning',
            'org.checkerframework.checker.interning.InterningChecker',
            ['-Astubs=javax-lang-model-element-name.astub'])
        createCheckTypeTask(project.name, 'NullnessOnlyAnnotatedFor',
            'org.checkerframework.checker.nullness.NullnessChecker',
            ['-AskipUses=com.sun.*', '-AuseConservativeDefaultsForUncheckedCode=source'])
        createCheckTypeTask(project.name, 'Purity',
            'org.checkerframework.framework.util.PurityChecker')
        createCheckTypeTask(project.name, 'Signature',
            'org.checkerframework.checker.signature.SignatureChecker')
        // These pass on some subprojects, which the `typecheck` task runs.
        // TODO: Incrementally add @AnnotatedFor on more classes.
        createCheckTypeTask(project.name, 'Nullness',
            'org.checkerframework.checker.nullness.NullnessChecker',
            ['-AskipUses=com.sun.*'])


        // Add jtregTests to framework and checker modules
        if (project.name.is('framework') || project.name.is('checker')) {
            tasks.create(name: 'jtregTests', dependsOn: ':downloadJtreg', group: 'Verification') {
                description 'Run the jtreg tests.'
                dependsOn('compileJava')
                dependsOn('compileTestJava')
                dependsOn('shadowJar')

                String jtregOutput = "${buildDir}/jtreg"
                String name = 'all'
                String tests = '.'
                doLast {
                    exec {
                        executable "${jtregHome}/bin/jtreg"
                        args = [
                                "-dir:${projectDir}/jtreg",
                                "-workDir:${jtregOutput}/${name}/work",
                                "-reportDir:${jtregOutput}/${name}/report",
                                "-verbose:error,fail",
                                // Don't add debugging information
                                //  "-javacoptions:-g",
                                "-keywords:!ignore",
                                "-samevm",
                                "-javacoptions:-classpath ${tasks.shadowJar.archiveFile.get()}:${sourceSets.test.output.asPath}",
                                // Required for checker/jtreg/nullness/PersistUtil.java and other tests
                                "-vmoptions:-classpath ${tasks.shadowJar.archiveFile.get()}:${sourceSets.test.output.asPath}",
                        ]
                        if (isJava8) {
                            // Use Error Prone javac and source/target 8
                            args += [
                                "-vmoptions:-Xbootclasspath/p:${configurations.javacJar.asPath}",
                                "-javacoptions:-Xbootclasspath/p:${configurations.javacJar.asPath}",
                                "-javacoptions:-source 8",
                                "-javacoptions:-target 8"
                                ]
                        } else {
                            args += [
                                    // checker/jtreg/nullness/defaultsPersist/ReferenceInfoUtil.java
                                    // uses the jdk.jdeps module.
                                    "-javacoptions:--add-modules jdk.jdeps",
                                    "-javacoptions:--add-exports=jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED",
                                    "-vmoptions:--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED",
                            ]
                        }
                        if (project.name.is('framework')) {
                            // Do not check for the annotated JDK
                            args += [
                                    "-javacoptions:-ApermitMissingJdk"
                            ]
                        } else if (project.name.is('checker')) {
                            args += [
                                    "-javacoptions:-classpath ${sourceSets.testannotations.output.asPath}",
                            ]
                        }

                        // Location of jtreg tests
                        args += "${tests}"
                    }
                }
            }
        }

        // Create a task for each JUnit test class whose name is the same as the JUnit class name.
        sourceSets.test.allJava.filter { it.path.contains('test/junit') }.forEach { file ->
            String junitClassName = file.name.replaceAll(".java", "")
            tasks.create(name: "${junitClassName}", type: Test) {
                description "Run ${junitClassName} tests."
                include "**/${name}.class"
            }
        }

        // Configure JUnit tests
        tasks.withType(Test) {
            if (isJava8) {
                jvmArgs "-Xbootclasspath/p:${configurations.javacJar.asPath}".toString()
            } else {
                jvmArgs += [
                        "--illegal-access=warn",
                        "--add-opens", "jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED",
                ]
            }

            maxParallelForks = Integer.MAX_VALUE

            if (project.name.is('checker')) {
                dependsOn('copyJarsToDist')
            }

            if (project.hasProperty('emit.test.debug')) {
                systemProperties += ["emit.test.debug": 'true']
            }

            testLogging {
                showStandardStreams = true
                // Always run the tests
                outputs.upToDateWhen { false }

                // Show the found unexpected diagnostics and expected diagnostics not found.
                exceptionFormat "full"
                events "failed"
            }

            // After each test, print a summary.
            afterSuite { desc, result ->
                if (desc.getClassName() != null) {
                    long mils = result.getEndTime() - result.getStartTime()
                    double seconds = mils / 1000.0

                    println "Testsuite: ${desc.getClassName()}\n" +
                            "Tests run: ${result.testCount}, " +
                            "Failures: ${result.failedTestCount}, " +
                            "Skipped: ${result.skippedTestCount}, " +
                            "Time elapsed: ${seconds} sec\n"
                }

            }
        }

        // Create a nonJunitTests task per project
        tasks.create(name: 'nonJunitTests', group: 'Verification') {
            description 'Run all Checker Framework tests except for the Junit tests and inference tests.'
            if (project.name.is('framework') || project.name.is('checker')) {
                dependsOn('jtregTests')
            }
            if (project.name.is('framework')) {
                dependsOn('loaderTests')
            }

            if (project.name.is('checker')) {
                if (!isJava8) {
                    dependsOn('jtregJdk11Tests')
                }
                dependsOn('nullnessExtraTests', 'commandLineTests', 'tutorialTests')
            }

            if (project.name.is('dataflow')) {
                dependsOn('liveVariableTest')
                dependsOn('issue3447Test')
            }
        }

        // Create an inferenceTests task per project
        tasks.create(name: 'inferenceTests', group: 'Verification') {
            description 'Run inference tests.'
            if (project.name.is('checker')) {
                dependsOn('wholeProgramInferenceTests', 'wpiManyTests', 'wpiPlumeLibTests')
            }
        }

        // Create a typecheck task per project (dogfooding the Checker Framework on itself).
        // This isn't a test of the Checker Framework as the test and nonJunitTests tasks are.
        // Tasks such as 'checkInterning' are constructed by createCheckTypeTask.
        tasks.create(name: 'typecheck', group: 'Verification') {
            description 'Run the Checker Framework on itself'
            dependsOn('checkFormatter', 'checkInterning', 'checkPurity', 'checkSignature')
            if (project.name.is('framework') || project.name.is('checker')) {
                dependsOn('checkNullnessOnlyAnnotatedFor', 'checkCompilerMessages')
            } else {
                dependsOn('checkNullness')
            }
        }

        // Create an allTests task per project.
        // allTests = test + nonJunitTests + inferenceTests + typecheck
        tasks.create(name: 'allTests', group: 'Verification') {
            description 'Run all Checker Framework tests'
            // The 'test' target is just the JUnit tests.
            dependsOn('test', 'nonJunitTests', 'inferenceTests', 'typecheck')
        }

        task javadocPrivate(dependsOn: javadoc) {
            doFirst {
                javadocMemberLevel = JavadocMemberLevel.PRIVATE
            }
            doLast {
                javadocMemberLevel = JavadocMemberLevel.PROTECTED
            }
        }
    }
}

assemble.dependsOn(':checker:copyJarsToDist')

task checkBasicStyle(group: 'Format') {
    description 'Check basic style guidelines, mostly whitespace.  Not related to Checkstyle tool.'
    String[] ignoreDirectories = ['.git',
                                  '.gradle',
                                  '.html-tools',
                                  '.idea',
                                  '.plume-scripts',
                                  '.run-google-java-format',
                                  'annotated',
                                  'api',
                                  'plume-bib',
                                  'bootstrap',
                                  'build',
                                  'jdk']

    String[] ignoreFilePatterns = [
            '*.aux',
            '*.bib',
            '*.class',
            '*.dvi',
            '*.expected',
            '*.gif',
            '*.jar',
            '*.jtr',
            '*.log',
            '*.out',
            '*.patch',
            '*.pdf',
            '*.png',
            '*.sty',
            '*.toc',
            '*.xcf',
            '*~',
            '#*#',
            'CFLogo.ai',
            'logfile.log.rec.index',
            'manual.html',
            'manual.html-e',
            'junit.*.properties',
            'securerandom.*',
            'checker/dist/META-INF/maven/org.apache.bcel/bcel/pom.xml',
            'checker/dist/META-INF/maven/org.apache.commons/commons-text/pom.xml',
            'framework/src/main/resources/git.properties']
    doLast {
        FileTree tree = fileTree(dir: projectDir)
        for (String dir : ignoreDirectories) {
            tree.exclude "**/${dir}/**"
        }
        for (String file : ignoreFilePatterns) {
            tree.exclude "**/${file}"
        }
        boolean failed = false
        tree.visit {
            if (!it.file.isDirectory()) {
                boolean blankLineAtEnd = false
                String fileName = it.file.getName()
                boolean checkTabs = !fileName.equals("Makefile")
                it.file.eachLine { line ->
                    if (line.endsWith(' ')) {
                        println("Trailing whitespace: ${it.file.absolutePath}")
                        failed = true
                    }
                    if (checkTabs && line.contains('\t')) {
                        println("Contains tab (use spaces): ${it.file.absolutePath}")
                        failed = true
                        checkTabs = false
                    }
                    if (!line.startsWith('\\') &&
                            (line.matches('^.* (else|finally|try)\\{}.*$')
                                    || line.matches('^.*}(catch|else|finally) .*$')
                                    || line.matches('^.* (catch|for|if|while)\\('))) {
                        // This runs on non-java files, too.
                        println("Missing space: ${it.file.absolutePath}")
                        failed = true
                    }
                    if (line.isEmpty()) {
                        blankLineAtEnd = true;
                    } else {
                        blankLineAtEnd = false;
                    }
                }

                if (blankLineAtEnd) {
                    println("Blank line at end of file: ${it.file.absolutePath}")
                    failed = true
                }

                RandomAccessFile file
                try {
                    file = new RandomAccessFile(it.file, 'r')
                    int end = file.length() - 1;
                    if (end > 0) {
                        file.seek(end)
                        byte last = file.readByte()
                        if (last != '\n') {
                            println("Missing newline at end of file: ${it.file.absolutePath}")
                            failed = true
                        }
                    }
                } finally {
                    if (file != null) {
                        file.close()
                    }
                }
            }
        }
        if (failed) {
            throw new GradleException("Files do not meet basic style guidelines.")
        }
    }
}
assemble.mustRunAfter(clean)
task buildAll(group: 'Build') {
    description 'Build all jar files, including source and javadoc jars'
    dependsOn(allJavadoc)
    subprojects { Project subproject ->
        dependsOn("${subproject.name}:assemble")
        dependsOn("${subproject.name}:javadocJar")
        dependsOn("${subproject.name}:sourcesJar")
    }
    dependsOn('framework:allJavadocJar', 'framework:allSourcesJar', 'checker:allJavadocJar', 'checker:allSourcesJar')
}

task releaseBuild(group: 'Build') {
    description 'Build everything required for a release'
    dependsOn(clean)
    doFirst {
        release = true
    }
    // Use finalizedBy rather than dependsOn so that release is set to true before any of the tasks are run.
    finalizedBy(buildAll)
}

// No group so it does not show up in the output of `gradlew tasks`
task releaseAndTest {
    description 'Build everything required for a release and run allTests'
    dependsOn(releaseBuild)
    subprojects { Project subproject ->
        dependsOn("${subproject.name}:allTests")
    }
}

// Don't create an empty checker-framework-VERSION.jar
jar.onlyIf {false}

/**
 * Adds the shared pom information to the given publication.
 * @param publication MavenPublication
 */
final sharedPublicationConfiguration(publication) {
    publication.pom {
        url = 'https://checkerframework.org'
        developers {
            // These are the lead developers/maintainers, not all the developers or contributors.
            developer {
                id = 'mernst'
                name = 'Michael Ernst'
                email = 'mernst@cs.washington.edu'
                url = 'https://homes.cs.washington.edu/~mernst/'
                organization = 'University of Washington'
                organizationUrl = 'https://www.cs.washington.edu/'
            }
            developer {
                id = 'smillst'
                name = 'Suzanne Millstein'
                email = 'smillst@cs.washington.edu'
                organization = 'University of Washington'
                organizationUrl = 'https://www.cs.washington.edu/'
            }
        }

        scm {
            url = 'https://github.com/typetools/checker-framework.git'
            connection = 'scm:git:git://github.com/typetools/checker-framework.git'
            developerConnection = 'scm:git:ssh://git@github.com/typetools/checker-framework.git'
        }
    }
}
