buildscript {
    repositories {
        maven { url '../../prebuilts/gradle-plugin' }
        maven { url '../../prebuilts/tools/common/m2/repository' }
        maven { url '../../prebuilts/tools/common/m2/internal' }
        maven { url "../../prebuilts/maven_repo/android" }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.5.0'
    }
}

ext.supportVersion = '23.2.0-SNAPSHOT'
ext.extraVersion = 25
ext.supportRepoOut = ''
ext.buildToolsVersion = '23.0.2'
ext.buildNumber = Integer.toString(ext.extraVersion)

/*
 * 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) {
    buildDir = new File(System.env.OUT_DIR + '/gradle/frameworks/support/build').getCanonicalFile()
    project.ext.distDir = new File(System.env.DIST_DIR).getCanonicalFile()

    // the build server does not pass the build number so we infer it from the last folder of the dist path.
    ext.buildNumber = project.ext.distDir.getName()
} else {
    buildDir = file('../../out/host/gradle/frameworks/support/build')
    project.ext.distDir = file('../../out/dist')
}

ext.supportRepoOut = new File(buildDir, 'support_repo')
ext.testApkDistOut = ext.distDir

// Main task called by the build server.
task(createArchive) << {
}


// upload anchor for subprojects to upload their artifacts
// to the local repo.
task(mainUpload) << {
}

// repository creation task
task createRepository(type: Zip, dependsOn: mainUpload) {
    from project.ext.supportRepoOut
    destinationDir project.ext.distDir
    into 'm2repository'
    baseName = String.format("sdk-repo-linux-m2repository-%s", project.ext.buildNumber)
}
createArchive.dependsOn createRepository

// prepare repository with older versions
task unzipRepo(type: Copy) {
    from "$rootDir/../../prebuilts/maven_repo/android"
    into project.ext.supportRepoOut
}

unzipRepo.doFirst {
    project.ext.supportRepoOut.deleteDir()
    project.ext.supportRepoOut.mkdirs()
}

// anchor for prepare repo. This is post unzip + sourceProp.
task(prepareRepo) << {
}

import com.google.common.io.Files
import com.google.common.base.Charsets

task(createXml) << {
    def repoArchive = createRepository.archivePath
    def repoArchiveName = createRepository.archiveName
    def size = repoArchive.length()
    def sha1 = getSha1(repoArchive)

    def xml =
"<sdk:sdk-addon xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:sdk=\"http://schemas.android.com/sdk/android/addon/6\">\n\
  <sdk:extra>\n\
    <sdk:revision>\n\
      <sdk:major>${project.ext.extraVersion}</sdk:major>\n\
    </sdk:revision>\n\
    <sdk:vendor-display>Android</sdk:vendor-display>\n\
    <sdk:vendor-id>android</sdk:vendor-id>\n\
    <sdk:name-display>Local Maven repository for Support Libraries</sdk:name-display>\n\
    <sdk:path>m2repository</sdk:path>\n\
    <sdk:archives>\n\
      <sdk:archive>\n\
       <sdk:size>${size}</sdk:size>\n\
       <sdk:checksum type=\"sha1\">${sha1}</sdk:checksum>\n\
       <sdk:url>${repoArchiveName}</sdk:url>\n\
      </sdk:archive>\n\
    </sdk:archives>\n\
  </sdk:extra>\n\
</sdk:sdk-addon>"

    Files.write(xml, new File(project.ext.distDir, 'repo-extras.xml'), Charsets.UTF_8)
}
createArchive.dependsOn createXml

task(createSourceProp) << {
    def sourceProp =
"Extra.VendorDisplay=Android\n\
Extra.Path=m2repository\n\
Archive.Arch=ANY\n\
Extra.NameDisplay=Android Support Repository\n\
Archive.Os=ANY\n\
Pkg.Revision=${project.ext.extraVersion}.0.0\n\
Extra.VendorId=android"

    Files.write(sourceProp, new File(project.ext.supportRepoOut, 'source.properties'), Charsets.UTF_8)
}
createSourceProp.dependsOn unzipRepo
prepareRepo.dependsOn createSourceProp

import com.google.common.hash.HashCode
import com.google.common.hash.HashFunction
import com.google.common.hash.Hashing
import java.nio.charset.Charset

def getSha1(File inputFile) {
    HashFunction hashFunction = Hashing.sha1()
    HashCode hashCode = hashFunction.hashString(inputFile.getAbsolutePath(), Charset.forName("UTF-8"))
    return hashCode.toString()
}

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

    apply plugin: 'maven'

    version = rootProject.ext.supportVersion
    group = 'com.android.support'

    repositories {
        maven { url "${project.parent.projectDir}/../../prebuilts/tools/common/m2/repository" }
        maven { url "${project.parent.projectDir}/../../prebuilts/tools/common/m2/internal" }
        maven { url "${project.parent.projectDir}/../../prebuilts/maven_repo/android" }
    }

    task release(type: Upload) {
        configuration = configurations.archives
        repositories {
            mavenDeployer {
                repository(url: uri("$rootProject.ext.supportRepoOut"))

                // Disable unique names for SNAPSHOTS so they can be updated in place.
                setUniqueVersion(false)
           }
        }
    }

    def deployer = release.repositories.mavenDeployer
    deployer.pom*.whenConfigured { pom ->
        pom.dependencies.findAll {dep -> dep.groupId == 'com.android.support' && dep.artifactId != 'support-annotations' }*.type = 'aar'
    }

    // before the upload, make sure the repo is ready.
    release.dependsOn rootProject.tasks.prepareRepo
    // make the mainupload depend on this one.
    mainUpload.dependsOn release

    project.plugins.whenPluginAdded { plugin ->
        if ("com.android.build.gradle.LibraryPlugin".equals(plugin.class.name)) {
            project.android.buildToolsVersion = rootProject.buildToolsVersion
        }
    }

    // Copy instrumentation test APK into the dist dir
    project.afterEvaluate {
        def assembleTestTask = project.tasks.findByPath('assembleAndroidTest')
        if (assembleTestTask != null) {
            assembleTestTask.doLast {
                // If the project actually has some instrumentation tests, copy its APK
                if (!project.android.sourceSets.androidTest.java.sourceFiles.isEmpty()) {
                    def pkgTask = project.tasks.findByPath('packageDebugAndroidTest')
                    copy {
                        from(pkgTask.outputFile)
                        into(rootProject.ext.testApkDistOut)
                    }
                }
            }
        }
    }
}

project.gradle.buildFinished { buildResult ->
    if (buildResult.getFailure() != null) {
        println()
        println 'Build failed. Possible causes include:'
        println '    1) Bad codes'
        println '    2) Out of date prebuilts in prebuilts/sdk'
        println '    3) Need to update the compileSdkVersion in a library\'s build.gradle'
        println()
    }
}

FileCollection getAndroidPrebuilt(String apiLevel) {
    files("$rootDir/../../prebuilts/sdk/$apiLevel/android.jar")
}
