import com.android.build.OutputFile

apply plugin: 'com.android.application'
apply plugin: 'com.google.android.gms.oss-licenses-plugin'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-parcelize'
apply plugin: 'kotlin-kapt'
apply plugin: 'placeholder-resolver'

kapt {
    correctErrorTypes = true
}

// Note: 2 digits max for each value
ext.versionMajor = 1
ext.versionMinor = 3
ext.versionPatch = 2

static def getGitTimestamp() {
    def cmd = 'git show -s --format=%ct'
    return cmd.execute().text.trim() as Long
}

static def generateVersionCodeFromTimestamp() {
    // It's unix timestamp, minus timestamp of October 3rd 2018 (first commit date) divided by 100: It's incremented by one every 100 seconds.
    // plus 20_000_000 for compatibility reason with the previous way the Version Code was computed
    // Note that the result will be multiplied by 10 when adding the digit for the arch
    return ((getGitTimestamp() - 1_538_524_800) / 100).toInteger() + 20_000_000
}

def generateVersionCodeFromVersionName() {
    // plus 4_000_000 for compatibility reason with the previous way the Version Code was computed
    // Note that the result will be multiplied by 10 when adding the digit for the arch
    return (versionMajor * 1_00_00 + versionMinor * 1_00 + versionPatch) + 4_000_000
}

def getVersionCode() {
    if (gitBranchName() == "develop") {
        return generateVersionCodeFromTimestamp()
    } else {
        return generateVersionCodeFromVersionName()
    }
}

static def gitRevision() {
    def cmd = "git rev-parse --short=8 HEAD"
    return cmd.execute().text.trim()
}

static def gitRevisionDate() {
    def cmd = "git show -s --format=%ci HEAD^{commit}"
    return cmd.execute().text.trim()
}

static def gitBranchName() {
    def fromEnv = System.env.BUILDKITE_BRANCH as String ?: ""

    if (!fromEnv.isEmpty()) {
        return fromEnv
    } else {
        // Note: this command return "HEAD" on Buildkite, so use the system env 'BUILDKITE_BRANCH' content first
        def cmd = "git rev-parse --abbrev-ref HEAD"
        return cmd.execute().text.trim()
    }
}

// For Google Play build, build on any other branch than main will have a "-dev" suffix
static def getGplayVersionSuffix() {
    if (gitBranchName() == "main") {
        return ""
    } else {
        return "-dev"
    }
}

static def gitTag() {
    def cmd = "git describe --exact-match --tags"
    return cmd.execute().text.trim()
}

// For F-Droid build, build on a not tagged commit will have a "-dev" suffix
static def getFdroidVersionSuffix() {
    if (gitTag() == "") {
        return "-dev"
    } else {
        return ""
    }
}

project.android.buildTypes.all { buildType ->
    buildType.javaCompileOptions.annotationProcessorOptions.arguments =
            [
                    validateEpoxyModelUsage: String.valueOf(buildType.name == 'debug')
            ]
}

// map for the version codes last digit
// x86 must have greater values than arm
// 64 bits have greater value than 32 bits
ext.abiVersionCodes = ["armeabi-v7a": 1, "arm64-v8a": 2, "x86": 3, "x86_64": 4].withDefault { 0 }

def buildNumber = System.env.BUILDKITE_BUILD_NUMBER as Integer ?: 0

android {



    // Due to a bug introduced in Android gradle plugin 3.6.0, we have to specify the ndk version to use
    // Ref: https://issuetracker.google.com/issues/144111441
    ndkVersion "21.3.6528147"

    compileSdk versions.compileSdk

    defaultConfig {
        applicationId "im.vector.app"
        // Set to API 21: see #405
        minSdk versions.minSdk
        targetSdk versions.targetSdk
        multiDexEnabled true

        renderscriptTargetApi 24
        renderscriptSupportModeEnabled true

        // `develop` branch will have version code from timestamp, to ensure each build from CI has a incremented versionCode.
        // Other branches (main, features, etc.) will have version code based on application version.
        versionCode project.getVersionCode()

        // Required for sonar analysis
        versionName "${versionMajor}.${versionMinor}.${versionPatch}-sonar"

        buildConfigField "String", "GIT_REVISION", "\"${gitRevision()}\""
        resValue "string", "git_revision", "\"${gitRevision()}\""

        buildConfigField "String", "GIT_REVISION_DATE", "\"${gitRevisionDate()}\""
        resValue "string", "git_revision_date", "\"${gitRevisionDate()}\""

        buildConfigField "String", "GIT_BRANCH_NAME", "\"${gitBranchName()}\""
        resValue "string", "git_branch_name", "\"${gitBranchName()}\""

        buildConfigField "String", "BUILD_NUMBER", "\"${buildNumber}\""
        resValue "string", "build_number", "\"${buildNumber}\""

        // The two booleans must not have the same value. We need two values for the manifest
        // LoginFlowV2 is disabled to be merged on develop (changelog: Improve login/register flow (#1410, #2585, #3172))
        resValue "bool", "useLoginV1", "true"
        resValue "bool", "useLoginV2", "false"

        // NotificationSettingsV2 is disabled. To be released in conjunction with iOS/Web
        def useNotificationSettingsV2 = true
        buildConfigField "Boolean", "USE_NOTIFICATION_SETTINGS_V2", "${useNotificationSettingsV2}"
        resValue "bool", "useNotificationSettingsV1", "${!useNotificationSettingsV2}"
        resValue "bool", "useNotificationSettingsV2", "${useNotificationSettingsV2}"

        buildConfigField "im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy", "outboundSessionKeySharingStrategy", "im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy.WhenTyping"

        buildConfigField "Long", "VOICE_MESSAGE_DURATION_LIMIT_MS", "120_000L"

        //  If set, MSC3086 asserted identity messages sent on VoIP calls will cause the call to appear in the room corresponding to the asserted identity.
        //  This *must* only be set in trusted environments.
        buildConfigField "Boolean", "handleCallAssertedIdentityEvents", "false"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

        // Keep abiFilter for the universalApk
        ndk {
            abiFilters "armeabi-v7a", "x86", 'arm64-v8a', 'x86_64'
        }

        // Ref: https://developer.android.com/studio/build/configure-apk-splits.html
        splits {
            // Configures multiple APKs based on ABI.
            abi {
                // Enables building multiple APKs per ABI.
                enable true

                // By default all ABIs are included, so use reset() and include to specify that we only
                // want APKs for armeabi-v7a, x86, arm64-v8a and x86_64.

                // Resets the list of ABIs that Gradle should create APKs for to none.
                reset()

                // Specifies a list of ABIs that Gradle should create APKs for.
                include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"

                // Generate a universal APK that includes all ABIs, so user who install from CI tool can use this one by default.
                universalApk true
            }
        }

        applicationVariants.all { variant ->
            // assign different version code for each output
            def baseVariantVersion = variant.versionCode * 10
            variant.outputs.each { output ->
                def baseAbiVersionCode = project.ext.abiVersionCodes.get(output.getFilter(OutputFile.ABI))
                // Known limitation: it does not modify the value in the BuildConfig.java generated file
                // See https://issuetracker.google.com/issues/171133218
                output.versionCodeOverride = baseVariantVersion + baseAbiVersionCode
                print "ABI " + output.getFilter(OutputFile.ABI) + " \t-> VersionCode = " + output.versionCodeOverride + "\n"
            }
        }

        // The following argument makes the Android Test Orchestrator run its
        // "pm clear" command after each test invocation. This command ensures
        // that the app's state is completely cleared between tests.
        testInstrumentationRunnerArguments clearPackageData: 'true'
    }

    testOptions {
        // Disables animations during instrumented tests you run from the command line…
        // This property does not affect tests that you run using Android Studio.”
        animationsDisabled = true

        execution 'ANDROIDX_TEST_ORCHESTRATOR'
    }

    signingConfigs {
        debug {
            keyAlias 'androiddebugkey'
            keyPassword 'android'
            storeFile file('./signature/debug.keystore')
            storePassword 'android'
        }
    }

    buildTypes {
        debug {
            applicationIdSuffix ".debug"
            resValue "string", "app_name", "Element dbg"

            resValue "bool", "debug_mode", "true"
            buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false"
            // Set to true if you want to enable strict mode in debug
            buildConfigField "boolean", "ENABLE_STRICT_MODE_LOGS", "false"

            signingConfig signingConfigs.debug
        }

        release {
            resValue "string", "app_name", "Element"

            resValue "bool", "debug_mode", "false"
            buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false"
            buildConfigField "boolean", "ENABLE_STRICT_MODE_LOGS", "false"

            postprocessing {
                removeUnusedCode true
                removeUnusedResources true
                // We do not activate obfuscation as it makes it hard then to read crash reports, and it's a bit useless on an open source project :)
                obfuscate false
                optimizeCode true
                proguardFiles 'proguard-rules.pro'
            }
        }
    }

    flavorDimensions "store"

    productFlavors {
        gplay {
            apply plugin: 'com.google.gms.google-services'
            afterEvaluate {
                tasks.matching { it.name.contains("GoogleServices") && !it.name.contains("Gplay") }*.enabled = false
            }

            dimension "store"
            isDefault = true
            versionName "${versionMajor}.${versionMinor}.${versionPatch}${getGplayVersionSuffix()}"

            resValue "bool", "isGplay", "true"
            buildConfigField "boolean", "ALLOW_FCM_USE", "true"
            buildConfigField "String", "SHORT_FLAVOR_DESCRIPTION", "\"G\""
            buildConfigField "String", "FLAVOR_DESCRIPTION", "\"GooglePlay\""
        }

        fdroid {
            dimension "store"

            versionName "${versionMajor}.${versionMinor}.${versionPatch}${getFdroidVersionSuffix()}"

            resValue "bool", "isGplay", "false"
            buildConfigField "boolean", "ALLOW_FCM_USE", "false"
            buildConfigField "String", "SHORT_FLAVOR_DESCRIPTION", "\"F\""
            buildConfigField "String", "FLAVOR_DESCRIPTION", "\"FDroid\""
        }
    }

    lintOptions {
        lintConfig file("lint.xml")

        checkDependencies true
        abortOnError true
    }

    compileOptions {
        sourceCompatibility versions.sourceCompat
        targetCompatibility versions.targetCompat
    }

    kotlinOptions {
        jvmTarget = "11"
    }

    sourceSets {
        androidTest {
            java.srcDirs += "src/sharedTest/java"
        }
        test {
            java.srcDirs += "src/sharedTest/java"
        }
    }

    buildFeatures {
        viewBinding true
    }
}

configurations {
    // videocache includes a sl4j logger which causes mockk to attempt to call the static android Log
    testImplementation.exclude group: 'org.slf4j', module: 'slf4j-android'
}

dependencies {

    implementation project(":matrix-sdk-android")
    implementation project(":matrix-sdk-android-rx")
    implementation project(":diff-match-patch")
    implementation project(":multipicker")
    implementation project(":attachment-viewer")
    implementation project(":library:ui-styles")
    implementation 'androidx.multidex:multidex:2.0.1'

    implementation libs.jetbrains.kotlinStdlibJdk7
    implementation libs.jetbrains.coroutinesCore
    implementation libs.jetbrains.coroutinesAndroid

    implementation libs.androidx.recyclerview
    implementation libs.androidx.appCompat
    implementation libs.androidx.fragmentKtx
    implementation libs.androidx.constraintLayout
    implementation "androidx.sharetarget:sharetarget:1.1.0"
    implementation libs.androidx.core
    implementation "androidx.media:media:1.4.2"
    implementation "androidx.transition:transition:1.4.1"

    implementation "org.threeten:threetenbp:1.4.0:no-tzdb"
    implementation "com.gabrielittner.threetenbp:lazythreetenbp:0.9.0"

    implementation libs.squareup.moshi
    kapt libs.squareup.moshiKotlin
    implementation libs.androidx.lifecycleExtensions
    implementation libs.androidx.lifecycleLivedata

    implementation libs.androidx.datastore
    implementation libs.androidx.datastorepreferences


    // Log
    implementation libs.jakewharton.timber

    // Debug
    implementation 'com.facebook.stetho:stetho:1.6.0'

    // Phone number https://github.com/google/libphonenumber
    implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.33'

    // rx
    implementation libs.rx.rxKotlin
    implementation libs.rx.rxAndroid
    implementation 'com.jakewharton.rxrelay2:rxrelay:2.1.1'
    // RXBinding
    implementation libs.jakewharton.rxbinding
    implementation libs.jakewharton.rxbindingAppcompat
    implementation libs.jakewharton.rxbindingMaterial

    implementation libs.airbnb.epoxy
    implementation libs.airbnb.epoxyGlide
    kapt libs.airbnb.epoxyProcessor
    implementation libs.airbnb.epoxyPaging
    implementation libs.airbnb.mvrx

    // Work
    implementation libs.androidx.work

    // Paging
    implementation libs.androidx.pagingRuntimeKtx

    // Functional Programming
    implementation libs.arrow.core

    // Pref
    implementation libs.androidx.preferenceKtx

    // UI
    implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
    implementation libs.google.material
    implementation 'me.gujun.android:span:1.7'
    implementation libs.markwon.core
    implementation libs.markwon.html
    implementation 'com.googlecode.htmlcompressor:htmlcompressor:1.5.2'
    implementation 'me.saket:better-link-movement-method:2.2.0'
    implementation 'com.google.android:flexbox:2.0.1'
    implementation libs.androidx.autoFill
    implementation 'jp.wasabeef:glide-transformations:4.3.0'
    implementation 'com.github.vector-im:PFLockScreen-Android:1.0.0-beta12'
    implementation 'com.github.hyuwah:DraggableView:1.0.0'
    implementation 'com.github.Armen101:AudioRecordView:1.0.5'

    // Custom Tab
    implementation 'androidx.browser:browser:1.3.0'

    // Passphrase strength helper
    implementation 'com.nulab-inc:zxcvbn:1.5.2'

    // To convert voice message on old platforms
    implementation 'com.arthenica:ffmpeg-kit-audio:4.5.LTS'

    // Alerter
    implementation 'com.tapadoo.android:alerter:7.0.1'

    implementation 'com.otaliastudios:autocomplete:1.1.0'

    // Shake detection
    implementation 'com.squareup:seismic:1.0.3'

    // Image Loading
    implementation libs.github.bigImageViewer
    implementation libs.github.glideImageLoader
    implementation libs.github.progressPieIndicator
    implementation libs.github.glideImageViewFactory

    // implementation 'com.github.MikeOrtiz:TouchImageView:3.0.2'
    implementation 'com.github.chrisbanes:PhotoView:2.3.0'

    implementation libs.github.glide
    kapt libs.github.glideCompiler
    implementation 'com.danikula:videocache:2.7.1'
    implementation 'com.github.yalantis:ucrop:2.2.7'

    // Badge for compatibility
    implementation 'me.leolin:ShortcutBadger:1.1.22@aar'

    // Chat effects
    implementation 'nl.dionsegijn:konfetti:1.3.2'
    implementation 'com.github.jetradarmobile:android-snowfall:1.2.1'
    // DI
    implementation libs.dagger.dagger
    kapt libs.dagger.daggerCompiler

    // gplay flavor only
    gplayImplementation('com.google.firebase:firebase-messaging:22.0.0') {
        exclude group: 'com.google.firebase', module: 'firebase-core'
        exclude group: 'com.google.firebase', module: 'firebase-analytics'
        exclude group: 'com.google.firebase', module: 'firebase-measurement-connector'
    }

    // OSS License, gplay flavor only
    gplayImplementation 'com.google.android.gms:play-services-oss-licenses:17.0.0'

    implementation "androidx.emoji:emoji-appcompat:1.1.0"

    implementation 'com.github.BillCarsonFr:JsonViewer:0.6'

    // WebRTC
    // org.webrtc:google-webrtc is for development purposes only
    // implementation 'org.webrtc:google-webrtc:1.0.+'
    implementation('com.facebook.react:react-native-webrtc:1.87.3-jitsi-6624067@aar')

    // Jitsi
    implementation('org.jitsi.react:jitsi-meet-sdk:3.1.0') {
        exclude group: 'com.google.firebase'
        exclude group: 'com.google.android.gms'
        exclude group: 'com.android.installreferrer'
    }

    // QR-code
    // Stick to 3.3.3 because of https://github.com/zxing/zxing/issues/1170
    implementation 'com.google.zxing:core:3.4.1'
    implementation 'me.dm7.barcodescanner:zxing:1.9.13'

    // Emoji Keyboard
    implementation libs.vanniktech.emojiMaterial
    implementation libs.vanniktech.emojiGoogle

    implementation 'im.dlg:android-dialer:1.2.5'

    // JWT
    api libs.jsonwebtoken.jjwtApi
    runtimeOnly libs.jsonwebtoken.jjwtImpl
    runtimeOnly(libs.jsonwebtoken.jjwtOrgjson) {
        exclude group: 'org.json', module: 'json' //provided by Android natively
    }
    implementation 'commons-codec:commons-codec:1.15'


    // TESTS
    testImplementation libs.tests.junit
    testImplementation libs.tests.kluent
    testImplementation libs.mockk.mockk
    // Plant Timber tree for test
    testImplementation libs.tests.timberJunitRule

    // Activate when you want to check for leaks, from time to time.
    //debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.3'

    androidTestImplementation libs.androidx.testCore
    androidTestImplementation libs.androidx.testRunner
    androidTestImplementation libs.androidx.testRules
    androidTestImplementation libs.androidx.junit
    androidTestImplementation libs.androidx.espressoCore
    androidTestImplementation libs.androidx.espressoContrib
    androidTestImplementation libs.androidx.espressoIntents
    androidTestImplementation libs.tests.kluent
    androidTestImplementation libs.androidx.coreTesting
    // Plant Timber tree for test
    androidTestImplementation libs.tests.timberJunitRule
    // "The one who serves a great Espresso"
    androidTestImplementation('com.adevinta.android:barista:4.2.0') {
        exclude group: 'org.jetbrains.kotlin'
    }
    androidTestUtil libs.androidx.orchestrator
}