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

import com.android.build.gradle.internal.coverage.JacocoReportTask
import com.android.build.gradle.internal.tasks.DeviceProviderInstrumentTestTask
import org.gradle.internal.os.OperatingSystem

import com.google.common.base.Charsets
import com.google.common.hash.HashCode
import com.google.common.hash.HashFunction
import com.google.common.hash.Hashing
import com.google.common.io.Files

import groovy.io.FileType

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 {
        // Keep gradle plugin version in sync with ub_supportlib-master manifest.
        classpath 'com.android.tools.build:gradle:2.2.4'
    }
}

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

configurations {
    doclava
}

dependencies {
    doclava project(':doclava')
}

ext.supportVersion = '25.2.0-SNAPSHOT'
ext.extraVersion = 41
ext.supportRepoOut = ''
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"

final String platform = OperatingSystem.current().isMacOsX() ? 'darwin' : 'linux'
System.setProperty('android.dir', "${rootDir}/../../")
final String fullSdkPath = "${rootDir}/../../prebuilts/fullsdk-${platform}"
if (file(fullSdkPath).exists()) {
    gradle.ext.currentSdk = 25
    ext.buildToolsVersion = '24.0.1'
    project.ext.androidJar = files("${fullSdkPath}/platforms/android-${gradle.ext.currentSdk}/android.jar")
    System.setProperty('android.home', "${rootDir}/../../prebuilts/fullsdk-${platform}")
    File props = file("local.properties")
    props.write "sdk.dir=${fullSdkPath}"
} else {
    gradle.ext.currentSdk = 'current'
    ext.buildToolsVersion = '24.0.1'
    project.ext.androidJar = files("${project.rootDir}/../../prebuilts/sdk/current/android.jar")
    File props = file("local.properties")
    props.write "android.dir=../../"
}

/*
 * 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) << {
}

// lint every library
task(lint) << {
}

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

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

// 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 = project.ext.androidJar

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

    // Default hidden errors + hidden superclass (111) and
    // deprecation mismatch (113) to match framework docs.
    final def hidden = [105, 107, 111, 112, 113, 115, 116, 121]

    doclavaErrors = (101..122) - hidden
    doclavaWarnings = []
    doclavaHidden += hidden

    options {
        addStringOption "templatedir",
                "${project.rootDir}/../../build/tools/droiddoc/templates-sdk"
        addStringOption "federate Android", "http://developer.android.com"
        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 = project.ext.androidJar

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

    // Check that the API we're building hasn't changed from the development
    // version. These typed of changes require an explicit API file update.
    checkApiErrors = (2..30)-[22]
    checkApiWarnings = []
    checkApiHidden = [22]

    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

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

    checkApiTaskPath = name
    updateApiTaskPath = updateApi.name

    // Check that the API we're building hasn't broken the last-released
    // library version. These types of changes are forbidden.
    checkApiErrors = (7..18)
    checkApiWarnings = [23, 24]
    checkApiHidden = (2..6) + (19..22) + (25..30)

    def lastReleasedApiFile = null
    def apiDir = new File(project.rootDir, 'api')
    apiDir.eachFileMatch FileType.FILES, ~/(\d+\.){3}txt/, { File apiFile ->
        if (lastReleasedApiFile == null || apiFile.name > lastReleasedApiFile.name) {
            lastReleasedApiFile = apiFile;
        }
    }

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

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'

    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 ->
        def isAndroidLibrary = "com.android.build.gradle.LibraryPlugin".equals(plugin.class.name)
        def isAndroidApp = "com.android.build.gradle.AppPlugin".equals(plugin.class.name)
        def isJavaLibrary = "org.gradle.api.plugins.JavaPlugin".equals(plugin.class.name)

        if (isAndroidLibrary || isAndroidApp) {
            project.android.buildToolsVersion = rootProject.buildToolsVersion

            // Enable code coverage for debug builds only if we are not running inside the IDE,
            // since enabling coverage reports breaks the method parameter resolution in the IDE
            // debugger.
            project.android.buildTypes.debug.testCoverageEnabled = !hasProperty('android.injected.invoked.from.ide')

            // Enforce NewApi lint check as fatal.
            project.android.lintOptions.check 'NewApi'
            project.android.lintOptions.fatal 'NewApi'
            project.parent.lint.dependsOn project.lint
        }

        if (isAndroidLibrary || isJavaLibrary) {
            // Add library to the aggregate dependency report.
            task allDeps(type: DependencyReportTask) {}

            // Create release and separate zip task for library.
            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)
                }
            }
        }
    }

    // Update the version meta-data in each Manifest
    project.afterEvaluate { p ->
        if (p.hasProperty('android')) {
            p.android.defaultConfig.manifestPlaceholders =
                    ["support-version": rootProject.ext.supportVersion]
        }
    }
}

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