apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

if (!gradle.hasProperty("mozconfig")) {
    apply plugin: 'org.mozilla.rust-android-gradle.rust-android'
}

android {
    namespace 'org.mozilla.appservices.full_megazord'

    compileSdk { version = release(config.compileSdkMajorVersion) { minorApiLevel = config.compileSdkMinorVersion } }

    defaultConfig {
        ndkVersion config.ndkVersion
        minSdkVersion config.minSdkVersion
        targetSdkVersion config.targetSdkVersion

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            consumerProguardFiles "$rootDir/proguard-rules-consumer-jna.pro"
        }
    }

    // Uncomment to include debug symbols in native library builds.
    // packagingOptions { doNotStrip "**/*.so" }
}

kotlin {
    jvmToolchain(rootProject.config.jvmTargetCompatibility)
}

// Configurations are a somewhat mysterious Gradle concept.  For our purposes, we can treat them
// sets of files produced by one component and consumed by another.
configurations {
    // Libraries for unit tests
    //
    // This is a JAR file that contains libmegazord and libjnidispatch built for desktop platforms
    // -- i.e. non-Android.  These include linux-x86-64, darwin-x86-64, and darwin-aarch64. These
    // libraries are needed to run unit tests, since the AAR packages only contain libraries for
    // Android.
    //
    // For libmegazord, we copy the desktop libs from the
    // [rust-android-gradle plugin](https://github.com/mozilla/rust-android-gradle), which is
    // configurable via `local.properties`. The official packages are built in taskcluster include
    // `linux-x86-64` and `darwin-x86-64` and the list is controlled by
    // taskcluster/kinds/module-build/kind.yml
    //
    // For libjnidispatch, we include all libraries included in the official JAR file.
    consumable("libsForTests")
    // Stores the JNA jar file
    jna {
        canBeConsumed = false
        canBeResolved = true
        canBeDeclared = true
    }
    // Native megazord library, this is the one compatible with the user's local machine.  We use it
    // to run uniffi-bindgen against.
    consumable("megazordNative")
}

dependencies {
    // Needed so we can copy the libraries into libsForTests.
    jna(libs.jna) {
        artifact {
            type = "jar"
        }
    }
}

if (!gradle.hasProperty("mozconfig")) {
    // Extract JNI dispatch libraries from the JAR into a directory, so that we can then package them
    // into our own megazord-desktopLibraries JAR.
    def extractLibJniDispatch = tasks.register("extractLibJniDispatch", Copy) {
        from zipTree(configurations.jna.singleFile).matching {
            include "**/libjnidispatch.*"
        }
        into layout.buildDirectory.dir("libjnidispatch").get()
    }

    def packageLibsForTest = tasks.register("packageLibsForTest", Jar) {
        archiveBaseName = "full-megazord-libsForTests"

        from extractLibJniDispatch
        from layout.buildDirectory.dir("rustJniLibs/desktop")
        dependsOn tasks["cargoBuild${rootProject.ext.nativeRustTarget.capitalize()}"]
    }

    def copyMegazordNative = tasks.register("copyMegazordNative", Copy) {
        from layout.buildDirectory.dir("rustJniLibs/desktop")
        into layout.buildDirectory.dir("megazordNative")
    }

    artifacts {
        // Connect task output to configurations
        libsForTests(packageLibsForTest)
        megazordNative(copyMegazordNative)
    }

    cargo {
        // The directory of the Cargo.toml to build.
        module = '..'

        // The Android NDK API level to target.
        apiLevel = rootProject.config.minSdkVersion

        // Where Cargo writes its outputs.
        targetDirectory = '../../../target'

        libname = 'megazord'

        // The Cargo targets to invoke.  The mapping from short name to target
        // triple is defined by the `rust-android-gradle` plugin.
        targets = rootProject.ext.rustTargets

        // Perform release builds (which should have debug info, due to
        // `debug = true` in Cargo.toml).
        profile = "release"

        exec = { spec, toolchain ->
            rootProject.ext.cargoExec(spec, toolchain)
            // Only used in the full megazord (that is, in this project) at build time.
            spec.environment("MEGAZORD_VERSION", config.componentsVersion)
        }

        extraCargoBuildArguments = rootProject.ext.extraCargoBuildArguments

        // Add a build-id so that our code works with simpleperf
        // https://bugzilla.mozilla.org/show_bug.cgi?id=1937916
        generateBuildId = true
    }
}

if (!gradle.hasProperty("mozconfig")) {
    androidComponents.onVariants(androidComponents.selector().all()) { variant ->
        // The `cargoBuild` task isn't available until after evaluation.
        afterEvaluate {
            tasks["merge${variant.name.capitalize()}JniLibFolders"].dependsOn(tasks["cargoBuild"])
        }
    }
}

apply from: "$appServicesRootDir/publish.gradle"
ext.configurePublish()

if (!gradle.hasProperty("mozconfig")) {
    afterEvaluate {
        publishing {
            publications {
                // Publish a second package named `full-megazord-libsForTests` to Maven with the
                // `libsForTests` output.  This contains the same content as our `libsForTests`
                // configuration. Publishing it allows the android-components code to depend on it.
                libsForTests(MavenPublication) {
                    artifact tasks['packageLibsForTest']
                    artifact file("${projectDir}/../DEPENDENCIES.md"), {
                        extension "LICENSES.md"
                    }
                    pom {
                        groupId = rootProject.config.componentsGroupId
                        artifactId = "${project.ext.artifactId}-libsForTests"
                        description = project.ext.description
                        // For mavenLocal publishing workflow, increment the version number every publish.
                        version = rootProject.config.componentsVersion + (rootProject.hasProperty('local') ? '-' + rootProject.property('local') : '')
                        packaging = "jar"

                        licenses {
                            license {
                                name = libLicense
                                url = libLicenseUrl
                            }
                        }

                        developers {
                            developer {
                                name = 'Sync Team'
                                email = 'sync-team@mozilla.com'
                            }
                        }

                        scm {
                            connection = libVcsUrl
                            developerConnection = libVcsUrl
                            url = libUrl
                        }
                    }

                    // This is never the publication we want to use when publishing a
                    // parent project with us as a child `project()` dependency.
                    alias = true
                }
            }
        }
    }
}
