import com.android.build.gradle.internal.coverage.JacocoReportTask
import com.android.build.gradle.internal.tasks.DeviceProviderInstrumentTestTask

import android.support.checkapi.CheckApiTask
import android.support.checkapi.UpdateApiTask
import android.support.doclava.DoclavaTask

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:2.2.0-alpha1'
    }
}

repositories {
    maven { url '../../prebuilts/tools/common/m2/repository' }
}

configurations {
    doclava
}

dependencies {
    doclava project(':doclava')
}

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

// Enforce the use of prebuilt dependencies in all sub-projects. This is
// required for the doclava dependency.
ext.usePrebuilts = "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) {
    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("${project.rootDir}/../../out/host/gradle/frameworks/support/build")
    project.ext.distDir = file("${project.rootDir}/../../out/dist")
}

ext.docsDir = new File(buildDir, 'javadoc')
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 "${project.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 android.support.build.ApiModule
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.Desc=Local Maven repository for Support Libraries\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

/**
 * Generates SHA1 hash for the specified file's absolute path.
 *
 * @param inputFile file to hash
 * @return SHA1 hash
 */
String getSha1(File inputFile) {
    HashFunction hashFunction = Hashing.sha1()
    HashCode hashCode = hashFunction.hashString(inputFile.getAbsolutePath(), Charset.forName("UTF-8"))
    return hashCode.toString()
}

/**
 * Returns the Android prebuilt JAR for the specified API level.
 *
 * @param apiLevel the API level or "current"
 * @return a file collection containing the Android prebuilt JAR
 */
FileCollection getAndroidPrebuilt(apiLevel) {
    files("${project.rootDir}/../../prebuilts/sdk/$apiLevel/android.jar")
}

/**
 * Populates the sub-project's set of source sets with the specified modules.
 *
 * @param subProject the sub-project to which the modules belong
 * @param apiModules the modules from which to populate
 */
void createApiSourceSets(Project subProject, List<ApiModule> apiModules) {
    subProject.ext._apiModules = apiModules
    subProject.ext.allSS = []
    if (gradle.ext.studioCompat.enableApiModules) {
        // nothing to do, they are all modules
        return
    }
    // create a jar task for the api specific internal implementations
    def internalJar = subProject.tasks.create(name: "internalJar", type: Jar) {
        baseName "internal_impl"
    }
    apiModules.each { ApiModule apiModule ->
        apiModule.sourceSet = createApiSourceset(subProject, apiModule.folderName, apiModule.folderName,
                apiModule.apiForSourceSet.toString(), apiModule.prev == null ? null : apiModule.prev.sourceSet)
        subProject.ext.allSS.add(apiModule.sourceSet)
    }
    subProject.android.libraryVariants.all { variant ->
        variant.javaCompile.dependsOn internalJar
    }
}

/**
 * Adds the specified module to the sub-project's set of source sets and
 * internal JAR. Also sets up dependencies, if supplied.
 *
 * @param subProject the sub-project to which the module belongs
 * @param name the name of the module
 * @param folder the module's source folder
 * @param apiLevel the module's compile API level
 * @param previousSource source set dependency (optional)
 * @return a source set for the module
 */
SourceSet createApiSourceset(Project subProject, String name, String folder, String apiLevel,
                       SourceSet previousSource) {
    def sourceSet = subProject.sourceSets.create(name)
    sourceSet.java.srcDirs = [folder]

    def configName = sourceSet.getCompileConfigurationName()

    subProject.getDependencies().add(configName, getAndroidPrebuilt(apiLevel))
    if (previousSource != null) {
        setupDependencies(subProject, configName, previousSource)
    }
    subProject.ext.allSS.add(sourceSet)
    subProject.tasks.internalJar.from sourceSet.output
    return sourceSet
}

/**
 * Adds the specified source set as a dependency for the sub-project.
 *
 * @param subProject the sub-project to modify
 * @param configName
 * @param previousSourceSet the source set to add as a dependency
 */
void setupDependencies(Project subProject, String configName, SourceSet previousSourceSet) {
    subProject.getDependencies().add(configName, previousSourceSet.output)
    subProject.getDependencies().add(configName, previousSourceSet.compileClasspath)
}

void setApiModuleDependencies(Project subProject, DependencyHandler handler, List extraDeps) {
    if (gradle.ext.studioCompat.enableApiModules) {
        subProject.android.enforceUniquePackageName=false
        // add dependency on the latest module
        handler.compile(project(subProject.ext._apiModules.last().moduleName))
    } else {
        handler.compile(files(subProject.tasks.internalJar.archivePath))
        def firstModule = subProject.ext._apiModules[0]
        extraDeps.each { dep ->
            handler."${firstModule.folderName}Compile"(project(dep))
            handler.compile(project(dep))
        }
    }
}

void registerForDocs(Project subProject, releaseVariant) {
    rootProject.generateApi.dependsOn releaseVariant.javaCompile
    rootProject.generateApi.source {
        def buildConfig = fileTree(releaseVariant.getGenerateBuildConfig().sourceOutputDir)
        return releaseVariant.javaCompile.source.minus(buildConfig) +
            fileTree(releaseVariant.aidlCompile.sourceOutputDir) +
            fileTree(releaseVariant.outputs[0].processResources.sourceOutputDir)
    }
    rootProject.generateApi.classpath += files(releaseVariant.javaCompile.classpath) +
            files(releaseVariant.javaCompile.destinationDir)

    if (subProject.hasProperty('allSS')) {
        subProject.allSS.each { ss ->
            rootProject.generateApi.source ss.java
        }
    }
}


// Generates API files.
task generateApi(type: DoclavaTask, dependsOn: configurations.doclava) {
    docletpath = configurations.doclava.resolve()
    destinationDir = project.docsDir

    // Base classpath is Android SDK, sub-projects add their own.
    classpath = getAndroidPrebuilt(gradle.ext.currentSdk)

    apiFile = new File(project.docsDir, 'release/current.txt')
    removedApiFile = new File(project.docsDir, 'release/removed.txt')
    generateDocs = false

    options {
        addStringOption "templatedir",
                "${project.rootDir}/../../build/tools/droiddoc/templates-sdk"
        addStringOption "federate Android", "http://developer.android.com"
        addStringOption "federationapi Android",
                "${project.rootDir}/../../prebuilts/sdk/api/24.txt"
        addStringOption "stubpackages", "android.support.*"
    }
    exclude '**/BuildConfig.java'
    exclude '**/R.java'
}

// Copies generated API files to current version.
task updateApi(type: UpdateApiTask, dependsOn: generateApi) {
    newApiFile = new File(project.docsDir, 'release/current.txt')
    oldApiFile = new File(project.rootDir, 'api/current.txt')
    newRemovedApiFile = new File(project.docsDir, 'release/removed.txt')
    oldRemovedApiFile = new File(project.rootDir, 'api/removed.txt')
}

// Checks generated API files against current version.
task checkApi(type: CheckApiTask, dependsOn: generateApi) {
    doclavaClasspath = generateApi.docletpath

    checkApiTaskPath = name
    updateApiTaskPath = updateApi.name

    newApiFile = new File(project.docsDir, 'release/current.txt')
    oldApiFile = new File(project.rootDir, 'api/current.txt')
    newRemovedApiFile = new File(project.docsDir, 'release/removed.txt')
    oldRemovedApiFile = new File(project.rootDir, 'api/removed.txt')
}
createArchive.dependsOn checkApi

subprojects {
    // Only modify android projects.
    if (project.name.equals('doclava')) return;

    // Change buildDir first so that all plugins pick up the new value.
    project.buildDir = project.file("$project.parent.buildDir/../$project.name/build")
    // current SDK is set in studioCompat.gradle
    project.ext.currentSdk = gradle.ext.currentSdk
    apply plugin: 'maven'
    project.ext.createApiSourceSets = this.&createApiSourceset
    project.ext.setApiModuleDependencies = this.&setApiModuleDependencies


    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)
                doLast {
                    // Remove any invalid maven-metadata.xml files that may have been created
                    // for SNAPSHOT versions that are *not* uniquely versioned.
                    pom*.each { pom ->
                        if (pom.version.endsWith('-SNAPSHOT')) {
                            final File artifactDir = new File(rootProject.ext.supportRepoOut,
                                    pom.groupId.replace('.', '/')
                                    + '/' + pom.artifactId
                                    + '/' + pom.version)
                            delete fileTree(dir: artifactDir, include: 'maven-metadata.xml*')
                        }
                    }
                }
           }
        }
    }

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

    def versionDir = {
        def groupDir = new File(rootProject.ext.supportRepoOut, project.group.replace('.','/'))
        def artifactDir = new File(groupDir, archivesBaseName)
        return new File(artifactDir, version)
    }

    task generateSourceProps(dependsOn: createRepository) << {
        def content = "Maven.GroupId=$deployer.pom.groupId\n" +
            "Maven.ArtifactId=$deployer.pom.artifactId\n" +
            "Maven.Version=$deployer.pom.version\n" +
            "Pkg.Desc=$project.name\n" +
            "Pkg.Revision=1\n" +
            "Dependencies=" +
            String.join(",", project.configurations.compile.allDependencies.collect {
                    def p = parent.findProject(it.name)
                    return p ? "$p.group:$p.archivesBaseName:$p.version" : null
                }.grep()) +
            "\n"
        Files.write(content, new File(versionDir(), 'source.properties'), Charsets.UTF_8)
    }

    task createSeparateZip(type: Zip, dependsOn: generateSourceProps)  {
        into archivesBaseName
        destinationDir project.parent.ext.distDir
        baseName = project.group
        version = project.parent.ext.buildNumber
    }
    project.parent.createArchive.dependsOn createSeparateZip

    // 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)
                || "com.android.build.gradle.AppPlugin".equals(plugin.class.name)) {
            project.android.buildToolsVersion = rootProject.buildToolsVersion
            // enable code coverage for debug builds only if we are not running inside the IDE
            // enabling coverage reports breaks the method parameter resolution in the IDE debugger
            project.android.buildTypes.debug.testCoverageEnabled = !hasProperty('android.injected.invoked.from.ide')
        }
    }

    project.afterEvaluate {
        // The archivesBaseName isn't available intially, so set it now
        def createZipTask = project.tasks.getByName("createSeparateZip")
        createZipTask.appendix = archivesBaseName
        createZipTask.from versionDir()

        // Copy instrumentation test APK into the dist dir
        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.afterEvaluate { p ->
        // remove dependency on the test so that we still get coverage even if some tests fail
        p.tasks.findAll { it instanceof JacocoReportTask}.each { task ->
            def toBeRemoved = new ArrayList()
            def dependencyList = task.taskDependencies.values
            dependencyList.each { dep ->
                if (dep instanceof String) {
                    def t = tasks.findByName(dep)
                    if (t instanceof DeviceProviderInstrumentTestTask) {
                        toBeRemoved.add(dep)
                        task.mustRunAfter(t)
                    }
                }
            }
            toBeRemoved.each { dep ->
                dependencyList.remove(dep)
            }
        }
    }

    project.afterEvaluate { p ->
        if (p.hasProperty('android')
                && p.android.hasProperty('libraryVariants')
                && !(p.android.hasProperty('noDocs') && p.android.noDocs)) {
            p.android.libraryVariants.all { v ->
                if (v.name == 'release') {
                    registerForDocs(p, v)
                }
            }
        }
    }
}

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