import groovy.json.JsonSlurper

// Top-level build file where you can add configuration options common to all
// sub-projects/modules.

buildscript {
    repositories {
        google()
        jcenter()
        repositories {
            maven { url 'https://maven.fabric.io/public' }
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.3.2'
        classpath 'com.google.gms:google-services:4.2.0'
        classpath 'io.fabric.tools:gradle:1.27.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files.
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        // React Native (JS, Obj-C sources, Android binaries) is installed from npm.
        maven { url "$rootDir/../node_modules/react-native/android" }
        // Android JSC is installed from npm.
        maven { url("$rootDir/../node_modules/jsc-android/dist") }
    }

    // Make sure we use the react-native version in node_modules and not the one
    // published in jcenter / elsewhere.
    configurations.all {
        resolutionStrategy {
            eachDependency { DependencyResolveDetails details ->
                if (details.requested.group == 'com.facebook.react'
                        && details.requested.name == 'react-native') {
                    def file = new File("$rootDir/../node_modules/react-native/package.json")
                    def version = new JsonSlurper().parseText(file.text).version
                    details.useVersion version
                }
            }
        }
    }

    // Third-party react-native modules which Jitsi Meet SDK for Android depends
    // on and which are not available in third-party Maven repositories need to
    // be deployed in a Maven repository of ours.
    //

    if (project.name.startsWith('react-native-')) {
        apply plugin: 'maven-publish'
        publishing {
            publications {}
            repositories {
                maven {
                    url rootProject.ext.mavenRepo
                    if (!rootProject.ext.mavenRepo.startsWith("file")) {
                        credentials {
                            username rootProject.ext.mavenUser
                            password rootProject.ext.mavenPassword
                        }
                    }
                }
            }
        }
    }

    // Use the number of seconds/10 since Jan 1 2019 as the version qualifier number.
    // This will last for the next ~680 years.
    // https://stackoverflow.com/a/38643838
    def versionQualifierNumber = (int)(((new Date().getTime()/1000) - 1546297200) / 10)

    afterEvaluate { project ->
        if (project.plugins.hasPlugin('android') || project.plugins.hasPlugin('android-library')) {
            project.android {
                compileSdkVersion rootProject.ext.compileSdkVersion
                buildToolsVersion rootProject.ext.buildToolsVersion
            }
        }

        if (project.name.startsWith('react-native-')) {
            def npmManifest = project.file('../package.json')
            def json = new JsonSlurper().parseText(npmManifest.text)

            // Release every dependency the SDK has with a -jitsi-XXX qualified version. This allows
            // us to pin the dependencies and make sure they are always updated, no matter what.

            project.version = "${json.version}-jitsi-${versionQualifierNumber}"

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

            publishing.publications {
                aarArchive(MavenPublication) {
                    groupId rootProject.ext.moduleGroupId
                    artifactId project.name
                    version project.version

                    artifact("${project.buildDir}/outputs/aar/${project.name}-release.aar") {
                        extension "aar"
                    }
                    artifact(androidSourcesJar)
                    pom.withXml {
                        def pomXml = asNode()
                        pomXml.appendNode('name', project.name)
                        pomXml.appendNode('description', json.description)
                        pomXml.appendNode('url', json.homepage)
                        if (json.license) {
                            def license = pomXml.appendNode('licenses').appendNode('license')
                            license.appendNode('name', json.license)
                            license.appendNode('distribution', 'repo')
                        }

                        def dependencies = pomXml.appendNode('dependencies')
                        configurations.getByName('releaseCompileClasspath').getResolvedConfiguration().getFirstLevelModuleDependencies().each {
                            def artifactId = it.moduleName
                            def version = it.moduleVersion
                            // React Native signals breaking changes by
                            // increasing the minor version number. So the
                            // (third-party) React Native modules we utilize can
                            // depend not on a specific react-native release but
                            // a wider range.
                            if (artifactId == 'react-native') {
                                def versionNumber = VersionNumber.parse(version)
                                version = "${versionNumber.major}.${versionNumber.minor}"
                            }

                            def dependency = dependencies.appendNode('dependency')
                            dependency.appendNode('groupId', it.moduleGroup)
                            dependency.appendNode('artifactId', artifactId)
                            dependency.appendNode('version', version)
                        }
                    }
                }
            }
        }
    }
}

ext {
    buildToolsVersion = "28.0.3"
    compileSdkVersion = 28
    minSdkVersion    = 21
    targetSdkVersion = 28
    supportLibVersion = "28.0.0"

    // The Maven artifact groupdId of the third-party react-native modules which
    // Jitsi Meet SDK for Android depends on and which are not available in
    // third-party Maven repositories so we have to deploy to a Maven repository
    // of ours.
    moduleGroupId = 'com.facebook.react'

    // Maven repo where artifacts will be published
    mavenRepo = System.env.MVN_REPO ?: ""
    mavenUser = System.env.MVN_USER ?: ""
    mavenPassword = System.env.MVN_PASSWORD ?: ""

    // Libre build
    libreBuild = (System.env.LIBRE_BUILD ?: "false").toBoolean()
}

// If Android SDK is not installed, accept its license so that it
// is automatically downloaded.
afterEvaluate { project ->
    // Either the environment variable ANDROID_HOME or the property sdk.dir in
    // local.properties identifies where Android SDK is installed.
    def androidHome = System.env.ANDROID_HOME
    if (!androidHome) {
        // ANDROID_HOME is not set. Is sdk.dir set?
        def file = file("${project.rootDir}/local.properties")
        def props = new Properties()
        if (file.canRead()) {
            file.withInputStream {
                props.load(it)
                androidHome = props.'sdk.dir'
            }
        }
        if (!androidHome && (!file.exists() || file.canWrite())) {
            // Neither ANDROID_HOME nor sdk.dir is set. Set sdk.dir (because
            // environment variables cannot be set).
            props.'sdk.dir' = "${project.buildDir}/android-sdk".toString()
            file.withOutputStream {
                props.store(it, null)
                androidHome = props.'sdk.dir'
            }
        }
    }
    // If the license is not accepted, accept it so that automatic downloading
    // kicks in.
    // The license hash can be taken from the accepted licenses, by doing this
    // on your local machine the file is
    // ${androidHome}/licenses/android-sdk-license
    if (androidHome) {
        def dir = file("${androidHome}/licenses")
        dir.mkdirs()
        def file = file("${dir.path}/android-sdk-license")
        if (!file.exists()) {
            file.withWriter {
                def hash = 'd56f5187479451eabf01fb78af6dfcb131a6481e'
                it.write(hash, 0, hash.length())
            }
        }
    }
}

// Force the version of the Android build tools we have chosen on all
// subprojects. The forcing was introduced for react-native and the third-party
// modules that we utilize such as react-native-background-timer.
subprojects { subproject ->
    afterEvaluate{
        if ((subproject.plugins.hasPlugin('android')
                    || subproject.plugins.hasPlugin('android-library'))
                && rootProject.ext.has('buildToolsVersion')) {
            android {
                buildToolsVersion rootProject.ext.buildToolsVersion
            }
        }
    }
}
