sourceSets {
    main {
        resources {
            // Stub files, message.properties, etc.
            srcDirs = ['src/main/java']
            exclude '**/*.java'
        }
    }
    testannotations
    test {
        java {
            // Tests that fail by design.
            exclude 'tests/SubtypingStringPatternsPartialTest.java'
        }
    }
}

dependencies {
    compile project(':dataflow')
    compile project(':javacutil')
    compile files("${stubparserJar}")
    compile files("${afuJar}")
    compileOnly project(':checker-qual')

    testCompile group: 'junit', name: 'junit', version: '4.12'
    testCompile project(':framework-test')
    testCompile sourceSets.testannotations.output
}

task checkDependencies() {
    doLast {
        if (!file(afuJar).exists()) {
            if (!file(stubparserJar).exists()) {
                throw new GradleException("${afuJar} and ${stubparserJar} do not exist. Try running './gradlew cloneAndBuildDependencies'")
            }
            throw new GradleException("${afuJar} does not exist. Try running './gradlew cloneAndBuildDependencies'")
        }
        if (!file(stubparserJar).exists()) {
            throw new GradleException("${stubparserJar} does not exist. Try running './gradlew cloneAndBuildDependencies'")
        }
    }
}

compileJava.dependsOn(checkDependencies)

task allSourcesJar(type: Jar) {
    description 'Creates a sources jar that includes sources for all Checker Framework classes in framework.jar'
    destinationDirectory = file("${projectDir}/dist")
    archiveFileName = "framework-source.jar"
    from (project(':framework').sourceSets.main.java,
            project(':dataflow').sourceSets.main.allJava,
            project(':javacutil').sourceSets.main.allJava)
}

task allJavadocJar(type: Jar) {
    description 'Creates javadoc jar include Javadoc for all of the framework'
    dependsOn rootProject.tasks.allJavadoc
    destinationDirectory = file("${projectDir}/dist")
    archiveFileName = "framework-javadoc.jar"
    from (project(':framework').tasks.javadoc.destinationDir,
            project(':dataflow').tasks.javadoc.destinationDir,
            project(':javacutil').tasks.javadoc.destinationDir)
}

shadowJar {
    description 'Creates the "fat" framework.jar in dist'
    destinationDirectory = file("${projectDir}/dist")
    archiveFileName = "framework.jar"
    manifest {
        attributes('Automatic-Module-Name': "org.checkerframework.framework")
    }
}

createCheckTypeTask(project.name, 'org.checkerframework.checker.compilermsgs.CompilerMessagesChecker', "CompilerMessages")
checkCompilerMessages {
    options.compilerArgs += [
            '-Apropfiles=' + sourceSets.main.resources.filter { file -> file.name.equals('messages.properties') }.asPath
    ]
}

task testWPI(type: Test) {
    doFirst {
        delete("tests/whole-program-inference/annotated")
    }
    outputs.upToDateWhen { false }
    include '**/WholeProgramInferenceTest.class'
    testLogging {
        // Always run the tests
        outputs.upToDateWhen { false }

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

task testWPIValidate(type: Test) {
    outputs.upToDateWhen { false }
    include '**/WholeProgramInferenceValidationTest.class'
    testLogging {
        // Always run the tests
        outputs.upToDateWhen { false }

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

task wholeProgramInferenceTests(dependsOn: 'shadowJar', group: 'Verification') {
    description 'Run tests for whole-program inference using .jaif files'
    dependsOn(compileTestJava)
    dependsOn(testWPI)
    outputs.upToDateWhen { false }

    doLast {
        // Copying all test files to another directory, removing all expected errors that should not
        // occur after inserting inferred annotations from .jaif files.
        copy {
            from files('tests/whole-program-inference/non-annotated')
            into file('tests/whole-program-inference/annotated')
            filter { String line ->
                line.contains('// :: error:') ? null : line
            }
        }
        // The only file for which expected errors are maintained is ExpectedErrors.java, so we copy it over
        delete('tests/whole-program-inference/annotated/ExpectedErrors.java')
        copy {
            from file('tests/whole-program-inference/non-annotated/ExpectedErrors.java')
            into file('tests/whole-program-inference/annotated')
        }

        // Inserting annotations from .jaif files in-place.
        List<File> jaifs = fileTree("${buildDir}/whole-program-inference/").matching {
            include '*.jaif'
        }.asList()
        List<File> javas = fileTree("tests/whole-program-inference/annotated/").matching {
            include '*.java'
        }.asList()
        exec {
            executable "${afu}/scripts/insert-annotations-to-source"
            args = ['-i']
            for (File jaif : jaifs) {
                args += [jaif.toString()]
            }
            for (File javaFile : javas) {
                args += [javaFile.toString()]
            }
        }
    }
    finalizedBy(testWPIValidate)
}

task loaderTests(dependsOn: 'shadowJar', group: 'Verification') {
    description 'Run tests for the annotation class loader'
    dependsOn(compileTestJava)
    // TODO: this dependency on checker is a bit ugly.
    dependsOn project(':checker-qual').tasks.jar
    dependsOn project(':checker').tasks.assemble
    doLast {
        exec {
            executable 'make'
            args = ['-C', "tests/annotationclassloader/", "all"]
        }
    }
}

clean {
    delete("tests/whole-program-inference/annotated")
}
