import android.support.doclava.DoclavaMultilineJavadocOptionFileOption
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'
    }
}

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

configurations {
    doclava
}

dependencies {
    doclava project(':doclava')
}

ext.supportVersion = '25.0.0'
ext.extraVersion = 39
ext.supportRepoOut = ''
ext.buildToolsVersion = '23.0.2'
ext.buildNumber = Integer.toString(ext.extraVersion)

ext.testRunnerVersion = '0.6-alpha'
ext.espressoVersion = '2.3-alpha'

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

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

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]

    // The Android gradle plugin doesn't touch Java sub-tasks, so we need to
    // manually set the Java task's boot classpath to the correct Android SDK.
    def compileJavaTaskName = sourceSet.getCompileJavaTaskName();
    def compileJavaOptions = subProject.tasks."${compileJavaTaskName}".options
    compileJavaOptions.bootClasspath = getAndroidPrebuilt(apiLevel)

    // Useful for cleaning up compiler warnings...
    //compileJavaOptions.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"

    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 registerForDocsTask(Task task, Project subProject, releaseVariant) {
    task.dependsOn releaseVariant.javaCompile
    task.source {
        def buildConfig = fileTree(releaseVariant.getGenerateBuildConfig().sourceOutputDir)
        return releaseVariant.javaCompile.source.minus(buildConfig) +
            fileTree(releaseVariant.aidlCompile.sourceOutputDir) +
            fileTree(releaseVariant.outputs[0].processResources.sourceOutputDir)
    }
    task.classpath += files(releaseVariant.javaCompile.classpath) +
            files(releaseVariant.javaCompile.destinationDir)

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

// Generates online docs.
task generateDocs(type: DoclavaTask, dependsOn: configurations.doclava) {
    docletpath = configurations.doclava.resolve()
    destinationDir = new File(project.docsDir, "online")

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

    def hdfOption = new DoclavaMultilineJavadocOptionFileOption('hdf')
    hdfOption.add(
            ['android.whichdoc', 'online'],
            ['android.hasSamples', 'true']);

    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.*"
        addStringOption "samplesdir", "${project.rootDir}/samples"
        addOption hdfOption
    }

    exclude '**/BuildConfig.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;

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

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

        // Create release and separate zip task for Android libraries (and android-annotations,
        // which is just a Java library).
        if ("com.android.build.gradle.LibraryPlugin".equals(plugin.class.name)
                || "org.gradle.api.plugins.JavaPlugin".equals(plugin.class.name)) {
            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'
            }

            ext.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" +
                        "Extra.VendorDisplay=Android\n" +
                        "Extra.VendorId=android\n" +
                        "Pkg.Desc=$project.name\n" +
                        "Pkg.Revision=1\n" +
                        "Maven.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.afterEvaluate {
        // The archivesBaseName isn't available intially, so set it now
        def createZipTask = project.tasks.findByName("createSeparateZip")
        if (createZipTask != null) {
            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') {
                    registerForDocsTask(rootProject.generateDocs, p, v)
                    registerForDocsTask(rootProject.generateApi, 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()
    }
}
