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

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.1.0'
    }
}

ext.supportVersion = '24.0.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 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

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

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

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

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

    }
}

def setupDependencies(Project subProject, String configName, SourceSet previousSourceSet) {
    subProject.getDependencies().add(configName, previousSourceSet.output)
    subProject.getDependencies().add(configName, previousSourceSet.compileClasspath)
}

subprojects {
    // 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'
    }

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

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