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

ext.supportVersion = '23.2.0-SNAPSHOT'
ext.extraVersion = 25
ext.supportRepoOut = ''
ext.buildToolsVersion = '22.1.0'
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')

// 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"))
            }
        }
    }

    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
        }
    }
}

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")
}
