apply plugin: 'maven-publish'
apply plugin: 'kotlin-android'
apply plugin: 'org.jetbrains.dokka'

def libOutputDir = "$buildDir/../../../Detox-android"

// The official javadoc equivalent that supports kotlin KDoc (see https://github.com/Kotlin/dokka)
dokka {

    // Note: this only remains valid as long as we didn't move kotlin code to src/main/kotlin instead fo src/main/java.
    // Will have to keep this up to date if we decided to do so.
    sourceDirs = files(android.sourceSets.main.java.srcDirs)

    // Nothing to add to what kotlinTasks() resolves on its own
//    classpath = []
//    classpath += files(android.bootClasspath)
//    classpath += files(project.configurations.getByName('compile').asList())
//    classpath += files(android.libraryVariants.collect { variant ->
//        variant.javaCompile.classpath.files
//    }.flatten())

    reportUndocumented = false
    skipEmptyPackages = true

    outputFormat = 'javadoc' // https://github.com/Kotlin/dokka#output-formats
    outputDirectory = "$buildDir/dokkaDoc" // Temp 'exploded' dir for .jar creation (i.e. by dokkaDocJar task)


    def suppressedPackages = ["android_libs", "com.wix.detox.espresso.common.annot"]
    for (String packagePrefix: suppressedPackages) {
        packageOptions {
            prefix = packagePrefix
            suppress = true
        }
    }

    // Side note / TODO:
    // Dokka outputs R and BuildConfig; currently, there's nothing to do about it, as issues such as
    // this on - https://github.com/Kotlin/dokka/issues/419 are still open :-/
    // We might want to revisit this in the future -- see if they've decided to export a custom classes
    // suppression config var or something.
}

task dokkaDocJar(type: Jar, dependsOn: dokka) {
    from "$buildDir/dokkaDoc"
    classifier = 'javadoc'
}

task sourcesJar(type: Jar) {
    from android.sourceSets.main.java.srcDirs
    classifier = 'sources'
}

project.afterEvaluate {
    project.tasks.all { Task task ->
        android.libraryVariants.all { variant ->
            def v = variant.name.capitalize()
            if (task.name == "publishMaven${v}AarPublicationToMavenRepository") {
                task.dependsOn "assemble${v}"

                // NOTE: Must "inject" this before actual publishing task run instead of inside publications def (see
                // below) because publications runs in the configuration phase (i.e. otherwise the check would run - and
                // fail, for *any* running gradle task, not just for publishing tasks).
                task.doFirst {
                    def versionName = System.getProperty('version')
                    if (versionName == null) {
                        throw new IllegalStateException("Publishing: Version not specified (should run 'gradle publish' with a -Dversion=1.2.3)")
                    }
                    logger.lifecycle("Publishing '$versionName' to: $libOutputDir")
                }
            }
        }
    }
}

publishing {
    repositories {
        maven {
            url = "$libOutputDir"
        }
    }

    publications {
        android.libraryVariants.all { variant ->
            if (variant.buildType.name == 'release') {
                def versionName = System.getProperty('version')

                "maven${variant.name.capitalize()}Aar"(MavenPublication) {
                    groupId 'com.wix'
                    artifactId 'detox'
                    version "$versionName"

                    // Register .aar as artifacts
                    variant.outputs.forEach { output ->
                        artifact output.outputFile
                    }
                    // Register sources, javadoc as artifacts
                    artifact sourcesJar
                    artifact dokkaDocJar

                    // Add some detox metadata to the .pom
                    pom {
                        name = 'Detox'
                        description = 'Gray box end-to-end testing and automation library for mobile apps'
                        url = 'https://github.com/wix/Detox'
                        scm {
                            connection = 'scm:git:git://github.com/wix/detox.git'
                            developerConnection = 'scm:git:git@github.com/wix/detox.git'
                            url = 'https://github.com/wix/detox'
                        }
                        licenses {
                            license {
                                name = "The MIT License"
                                url = "https://github.com/wix/Detox/blob/master/LICENSE"
                            }
                        }
                    }

                    // Add detox dependencies to the .pom
                    pom.withXml {
                        final rootNode = asNode().appendNode('dependencies')
                        addConfigurationDependencies(rootNode, configurations.api, "compile")
                        addConfigurationDependencies(rootNode, configurations.compile, "compile")
                        addConfigurationDependencies(rootNode, configurations.implementation, "runtime")
                    }
                }
            }
        }
    }

    // Based on https://stackoverflow.com/a/42160584/453052
    ext.addConfigurationDependencies = { rootNode, Configuration configuration, String scope ->
        configuration.dependencies.each { dep -> addChildDependency(rootNode, dep, scope) }
    }

    ext.addChildDependency = { rootNode, Dependency dep, String scope ->
        if (dep.group == null || dep.version == null || dep.name == null || dep.name == "unspecified")
            return

        final childNode = rootNode.appendNode('dependency')
        childNode.appendNode('groupId', dep.group)
        childNode.appendNode('artifactId', dep.name)
        childNode.appendNode('version', dep.version)
        childNode.appendNode('scope', scope)

        if (!dep.transitive) {
            // If this dependency is transitive, we should force exclude all its dependencies them from the POM
            final exclusionNode = childNode.appendNode('exclusions').appendNode('exclusion')
            exclusionNode.appendNode('groupId', '*')
            exclusionNode.appendNode('artifactId', '*')
        } else if (!dep.properties.excludeRules.empty) {
            // Otherwise add specified exclude rules
            final exclusionNode = childNode.appendNode('exclusions').appendNode('exclusion')
            dep.properties.excludeRules.each { ExcludeRule rule ->
                exclusionNode.appendNode('groupId', rule.group ?: '*')
                exclusionNode.appendNode('artifactId', rule.module ?: '*')
            }
        }
    }
}
