import org.gradle.plugins.ide.idea.model.IdeaModel

buildscript {
    repositories {
        google()
        jcenter()
        gradlePluginPortal()
    }

    dependencies {
        gradle
        classpath 'com.android.tools.build:gradle:3.5.3'
        classpath 'net.ltgt.gradle:gradle-errorprone-plugin:0.6'
        classpath 'com.netflix.nebula:gradle-aggregate-javadocs-plugin:2.2.1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.41"
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        mavenCentral()
    }

    group = "org.robolectric"
    version = thisVersion
}

apply plugin: 'idea'

project.ext.configAnnotationProcessing = []
project.afterEvaluate {
    def ideaProject = rootProject.extensions.getByType(IdeaModel).project
    ideaProject.ipr.withXml { provider ->
        def compilerConfiguration = provider.asNode().component.find { it.'@name' == 'CompilerConfiguration' }

        // prevent compiler from complaining about duplicate classes...
        def excludeFromCompile = compilerConfiguration.appendNode 'excludeFromCompile'
        configAnnotationProcessing.each { Project subProject ->
            excludeFromCompile.appendNode('directory',
                    [url: "file://${subProject.buildDir}/classes/java/main/generated", includeSubdirectories: "true"])
        }

        // replace existing annotationProcessing tag with a new one...
        compilerConfiguration.annotationProcessing.replaceNode {
            annotationProcessing {
                configAnnotationProcessing.each { Project subProject ->
                    profile(name: "${subProject.name}_main", enabled: "true") {
                        module(name: "${subProject.name}_main")
                        option(name: "org.robolectric.annotation.processing.shadowPackage",
                                value: subProject.shadows.packageName)
                        processor(name: "org.robolectric.annotation.processing.RobolectricProcessor")

                        processorPath(useClasspath: "false") {
                            def processorRuntimeCfg = project.project(":processor").configurations['runtime']
                            processorRuntimeCfg.allArtifacts.each { artifact ->
                                entry(name: artifact.file)
                            }
                            processorRuntimeCfg.files.each { file ->
                                entry(name: file)
                            }
                        }
                    }
                }
            }
        }
    }
}

apply plugin: 'nebula-aggregate-javadocs'

rootProject.gradle.projectsEvaluated {
    rootProject.tasks['aggregateJavadocs'].failOnError = false
}

gradle.projectsEvaluated {
    def headerHtml = "<ul class=\"navList\" style=\"font-size: 1.5em;\"><li>Robolectric $thisVersion |" +
            " <a href=\"/\" target=\"_top\">" +
            "<img src=\"http://robolectric.org/images/logo-with-bubbles-down.png\"" +
            " style=\"max-height: 18pt; vertical-align: sub;\"/></a></li></ul>"
    project.allprojects { p ->
        p.tasks.withType(Javadoc) {
            options {
                noTimestamp = true
                links = [
                        "https://docs.oracle.com/javase/8/docs/api/",
                        "https://developer.android.com/reference/",
                ]
                header = headerHtml
                footer = headerHtml
//                bottom = "<link rel=\"stylesheet\" href=\"http://robolectric.org/assets/css/main.css\">"
                version = thisVersion
            }
        }
    }
}

task aggregateJsondocs(type: Copy) {
    gradle.projectsEvaluated {
        project.subprojects.findAll { it.plugins.hasPlugin(ShadowsPlugin) }.each { subproject ->
            dependsOn subproject.tasks["compileJava"]
            from "${subproject.buildDir}/docs/json"
        }
    }
    into "$buildDir/docs/json"
}

task aggregateDocs {
    dependsOn ':aggregateJavadocs'
    dependsOn ':aggregateJsondocs'
}

// aggregate test results from all projects...
task aggregateTestReports(type: TestReport) {
    def jobNumber = System.getenv('TRAVIS_JOB_NUMBER')
    if (jobNumber == null) {
        destinationDir = file("$buildDir/reports/allTests")
    } else {
        destinationDir = file("$buildDir/reports/allTests/$jobNumber")
    }
}

afterEvaluate {
    def aggregateTestReportsTask = rootProject.tasks['aggregateTestReports']

    allprojects.each { p ->
        p.afterEvaluate {
            p.tasks.withType(Test) { t ->
                aggregateTestReportsTask.reportOn binResultsDir
                finalizedBy aggregateTestReportsTask
            }
        }
    }
}

task prefetchSdks() {
    AndroidSdk.ALL_SDKS.each { androidSdk ->
        doLast {
            println("Prefetching ${androidSdk.coordinates}...")
            // prefetch into maven local repo...
            def mvnCommand = "mvn -q dependency:get -DrepoUrl=http://maven.google.com \
                -DgroupId=${androidSdk.groupId} -DartifactId=${androidSdk.artifactId} \
                -Dversion=${androidSdk.version}"
            shellExec(mvnCommand)

            // prefetch into gradle local cache...
            def config = configurations.create("sdk${androidSdk.apiLevel}")
            dependencies.add("sdk${androidSdk.apiLevel}", androidSdk.coordinates)
            // causes dependencies to be resolved:
            config.files
        }
    }
}

private void shellExec(String mvnCommand) {
    def process = mvnCommand.execute()
    def out = new StringBuffer()
    def err = new StringBuffer()
    process.consumeProcessOutput(out, err)
    process.waitFor()
    if (out.size() > 0) println out
    if (err.size() > 0) println err
    if (process.exitValue() != 0) System.exit(1)
}

task prefetchDependencies() {
    doLast {
        allprojects.each { p ->
            p.configurations.each { config ->
                // causes dependencies to be resolved:
                if (config.isCanBeResolved()) {
                    try {
                        config.files
                    } catch (org.gradle.api.artifacts.ResolveException e) {
                        // ignore resolution issues for integration tests, sigh
                        if (!p.path.startsWith(":integration_tests:")) {
                            throw e
                        }
                    }
                }
            }
        }
    }
}

// for use of external initialization scripts...
project.ext.allSdks = AndroidSdk.ALL_SDKS
