import com.android.build.gradle.api.LibraryVariant

apply plugin: 'java'

// The paths of Android projects that should be included in the jar and javadoc.
static def getAndroidPathsForJar() {
    [':third_party:gif_decoder', ':library']
}

// The paths of Java projects that should be included in the jar and javadoc.
static def getJavaPathsForJar() {
    [':third_party:disklrucache']
}

// The paths of Android projects that should be included only in Javadoc, not in the jar.
static def getAndroidPathsForJavadoc() {
    [
            ':integration:okhttp',
            ':integration:okhttp3',
            ':integration:volley',
            ':integration:gifencoder',
            ':integration:recyclerview'
    ]
}

// The paths of Java projects that should be included only in Javadoc, not in the jar.
static def getJavaPathsForJavadoc() {
    [':annotation']
}

(getAndroidPathsForJavadoc() + getAndroidPathsForJar() +
        getJavaPathsForJar() + getJavaPathsForJavadoc()).each {
    evaluationDependsOn(it)
}

def asProjects(paths) {
    paths.collect { String path -> project(path) }
}

def getAndroidSdkDirectory() {
    project(':library').android.sdkDirectory
}

def getAndroidCompileSdkVersion() {
    project(':library').android.compileSdkVersion
}

def getInternalAndroidProjectsForJar() {
    asProjects(getAndroidPathsForJar())
}

def getInternalJavaProjectsForJar() {
    asProjects(getJavaPathsForJar())
}

def getInternalAndroidProjectsForJavadoc() {
    asProjects(getAndroidPathsForJavadoc())
}

def getInternalJavaProjectsForJavadoc() {
    asProjects(getJavaPathsForJavadoc())
}

def getAndroidProjectsForJar() {
    getAndroidLibraryVariantsForJar('debug')
}

def getAndroidLibraryVariantsForJar(variantName) {
    getAndroidLibraryVariants(getInternalAndroidProjectsForJar(), variantName)
}

def getAndroidLibraryVariantsForJavadoc(variantName) {
    getAndroidLibraryVariants(getInternalAndroidProjectsForJavadoc(), variantName)
}

static def getAndroidLibraryVariants(projects, variantName) {
    projects.collect { project ->
        project.android.libraryVariants.findAll { type ->
            type.buildType.name.equalsIgnoreCase(variantName)
        }
    }.sum()
}

def getSourceFilesForVariantJar(variantName) {
    getAndroidLibraryVariantsForJar(variantName).collect {
        it.getJavaCompiler().source.findAll {
            return !it.getName().equals("R.java") && !it.getName().equals("BuildConfig.java")
        }
    } + getInternalJavaProjectsForJar().collect { it.sourceSets.main.allJava }
}

def getSourceFilesForVariantJavadoc(variantName) {
    getAndroidLibraryVariantsForJavadoc(variantName).collect { it.getJavaCompiler().source } +
            getInternalJavaProjectsForJavadoc().collect { it.sourceSets.main.allJava }
}

def getAndroidJar() {
    "${getAndroidSdkDirectory()}/platforms/${getAndroidCompileSdkVersion()}/android.jar"
}

project.archivesBaseName = "${POM_ARTIFACT_ID}-${VERSION_NAME}"

// Generate javadocs and sources containing batched documentation and sources for all internal
// projects.
['debug'].each { variantName ->

    task("${variantName}SourceJar", type: Jar) {
        from getSourceFilesForVariantJar(variantName)
    }

    def javadocTask = tasks.create("${variantName}Javadoc", Javadoc) {
        source = getSourceFilesForVariantJar(variantName)
        source += getSourceFilesForVariantJavadoc(variantName)

        doFirst {
            it.classpath =
                    project.files(
                            getAndroidJar(),
                            getAndroidLibraryVariantsForJar(variantName).collect {
                                LibraryVariant lib -> lib.getJavaCompiler().classpath.files
                            },
                            getAndroidLibraryVariantsForJavadoc(variantName).collect {
                                LibraryVariant lib -> lib.getJavaCompiler().classpath.files
                            },
                            getInternalJavaProjectsForJavadoc().collect { Project project ->
                                project.sourceSets.main.compileClasspath.files
                            },
                            getInternalJavaProjectsForJar().collect { Project project ->
                                project.sourceSets.main.compileClasspath.files
                            },
                            // Finds dependencies of Android packages that would otherwise be
                            // ignored (Volley in particular)
                            getInternalAndroidProjectsForJavadoc().collect { Project project ->
                                project.file('build/intermediates/classes/debug')
                            }
            )
        }

        options {
            links("http://docs.oracle.com/javase/7/docs/api/")
            links("https://square.github.io/okhttp/3.x/okhttp/")
            links("https://square.github.io/okhttp/2.x/okhttp/")
            linksOffline("http://d.android.com/reference",
                    "${getAndroidSdkDirectory()}/docs/reference")
        }

        exclude '**/BuildConfig.java'
        exclude '**/R.java'
    }

    def cleanJavadocTask = task("clean${variantName.capitalize()}Javadoc", type: Delete) {
        delete javadocTask.destinationDir
    } as Task
    clean.dependsOn(cleanJavadocTask)

    def javadocJarTask = task("${variantName}JavadocJar", type: Jar) {
        from javadocTask.destinationDir
    } as Task
    javadocJarTask.dependsOn(javadocTask)
}

jar {
    from files(
            getAndroidProjectsForJar().collect { LibraryVariant variant ->
                variant.getJavaCompiler().destinationDir
            }
    )
    from files(getInternalJavaProjectsForJar().collect { it.sourceSets.main.output })
    exclude "**/R.class"
    exclude "**/BuildConfig.class"
    exclude "**/R\$*.class"
    exclude "android/**"
}

(getInternalAndroidProjectsForJar() + getInternalAndroidProjectsForJavadoc()).each {
    project ->
        debugJavadoc.dependsOn(project.tasks.compileDebugSources)
        jar.dependsOn(project.tasks.compileDebugSources)
}

(getInternalJavaProjectsForJar() + getInternalJavaProjectsForJavadoc()).each {
    project ->
        debugJavadoc.dependsOn(project.tasks.compileJava)
        jar.dependsOn(project.tasks.compileJava)
}

artifacts {
    archives debugJavadocJar {
        classifier 'javadoc'
    }
    archives debugSourceJar {
        classifier 'sources'
    }
}
