allprojects { subproject ->
    tasks.withType(JavaForkOptions) {
        // Prevent forked processes from stealing focus (on MacOS at least)
        jvmArgs '-Djava.awt.headless=true'
    }
}

/*
 * With the build server you are given two env variables.
 * The OUT_DIR is a temporary directory you can use to put things during the build.
 * The DIST_DIR is where you want to save things from the build.
 *
 * The build server will copy the contents of DIST_DIR to somewhere and make it available.
 */
if (System.env.DIST_DIR != null && System.env.OUT_DIR != null) {
    ext.androidHostOut = file(System.env.OUT_DIR)
    ext.androidHostDist = file(System.env.DIST_DIR)
} else {
    // ext.androidHostOut is shared by all tools/{base,build,swt} gradle projects/
    ext.androidHostOut = file("$rootDir/../out")
    ext.androidHostDist = new File(ext.androidHostOut, "dist")
}


// rootProject.buildDir is specific to this gradle build.
buildDir = new File(ext.androidHostOut, "build/root")

// apply this after the buildDir has been changed.
apply plugin: 'sdk-emulator'

ext.localRepo = project.hasProperty('localRepo') ? localRepo : "$ext.androidHostOut/repo"

apply from: "$rootDir/buildSrc/base/version.gradle"

subprojects { Project project ->
    // Change buildDir first so that all plugins pick up the new value.
    project.buildDir = project.file("$project.parent.buildDir/../$project.name/build")
}

// delay evaluation of this project before all subprojects have been evaluated.
subprojects.each { subproject -> evaluationDependsOn(subproject.path) }

def testTasks = subprojects.collect { it.tasks.withType(Test) }.flatten()

// Print failed tests to the console early.
testTasks.each { task ->
    task.testLogging {
        events "failed", "skipped"
    }
}

task aggregateResults(type: Copy) {
    from { testTasks*.binResultsDir*.parentFile*.parentFile }
    into { file("$buildDir/results") }
}

task prepareRepo(type: Copy) {
    from { rootProject.cloneArtifacts.repository }
    into { "$rootProject.ext.androidHostOut/repo" }
}

task copyGradleProperty(type: Copy) {
    from { "${System.env.HOME}/.gradle/gradle.properties" }
    into { gradle.gradleUserHomeDir }
}

tasks.create(name: 'publishLocal')
subprojects { project ->
    if (project.tasks.findByName('publishLocal') != null) {
        rootProject.publishLocal.dependsOn project.publishLocal
    }
}

task setupGradleInIde << {
    File dir = gradle.gradleHomeDir
    File gradleDistLink = new File(project.ext.androidHostOut, "gradle-dist-link")
    if (gradleDistLink.exists()) {
        gradleDistLink.delete()
    }
    String link = dir.path.substring(project.ext.androidHostOut.path.length() + 1)
    String command = "ln -s $link ${gradleDistLink.path}"
    command.execute()
}

// basic task for custom distribution of project should the build server.
task dist << {
}

task clean << {
  delete 'build'

  new File("$localRepo/com/android/tools").eachFile {
    if (it.name != "external") {
      delete it
    }
  }
}
apply plugin: 'presubmit-runner'
// Task for initializing a fresh repo.
task init {
  dependsOn prepareRepo
  dependsOn setupGradleInIde
  dependsOn copyGradleProperty
}
