plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
    id 'org.jlleitschuh.gradle.ktlint'
}

def gitDescribe = { ->
    def stdout = new ByteArrayOutputStream()
    exec {
        commandLine 'git', 'describe', '--always', '--tags', '--dirty=-dirty'
        standardOutput = stdout
    }
    return stdout.toString().trim()
}

android {
    namespace 'com.stevesoltys.seedvault'
    compileSdk rootProject.ext.compileSdk

    defaultConfig {
        minSdk rootProject.ext.minSdk
        targetSdk rootProject.ext.targetSdk
        versionNameSuffix "-$gitDescribe"
        testInstrumentationRunner "com.stevesoltys.seedvault.KoinInstrumentationTestRunner"
        testInstrumentationRunnerArguments disableAnalytics: 'true'

        if (project.hasProperty('instrumented_test_size')) {
            final testSize = project.getProperty('instrumented_test_size')
            println("Instrumented test size: $testSize")

            testInstrumentationRunnerArguments size: testSize
        }
    }

    buildTypes {
        release {
            minifyEnabled false
        }
    }

    lint {
        disable "DialogFragmentCallbacksDetector",
                "InvalidFragmentVersionForActivityResult",
                "CheckedExceptions"
        abortOnError true
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_17.toString()
        languageVersion = "1.8"
    }
    packagingOptions {
        exclude("META-INF/LICENSE.md")
        exclude("META-INF/LICENSE-notice.md")
    }
    testOptions {
        unitTests.all {
            useJUnitPlatform()
            testLogging {
                events "passed", "skipped", "failed"
            }
        }
        unitTests {
            includeAndroidResources = true
        }
    }

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

    signingConfigs {
        aosp {
            // Generated from the AOSP platform key:
            // https://android.googlesource.com/platform/build/+/refs/tags/android-11.0.0_r29/target/product/security/platform.pk8
            keyAlias "platform"
            keyPassword "platform"
            storeFile file("development/platform.jks")
            storePassword "platform"
        }
    }

    buildTypes.release.signingConfig = signingConfigs.aosp
    buildTypes.debug.signingConfig = signingConfigs.aosp
}

dependencies {
    compileOnly rootProject.ext.aosp_libs

    /**
     * Dependencies in AOSP
     *
     * We try to keep the dependencies in sync with what AOSP ships as Seedvault is meant to be built
     * with the AOSP build system and gradle builds are just for more pleasant development.
     * Using the AOSP versions in gradle builds allows us to spot issues early on.
     */
    implementation rootProject.ext.kotlin_libs.std
    // These coroutine libraries get upgraded otherwise to versions incompatible with kotlin version
    implementation rootProject.ext.kotlin_libs.coroutines

    implementation rootProject.ext.std_libs.androidx_core
    // A newer version gets pulled in with AOSP via core, so we include fragment here explicitly
    implementation rootProject.ext.std_libs.androidx_fragment
    implementation rootProject.ext.std_libs.androidx_activity
    implementation rootProject.ext.std_libs.androidx_preference
    implementation rootProject.ext.std_libs.androidx_lifecycle_viewmodel_ktx
    implementation rootProject.ext.std_libs.androidx_lifecycle_livedata_ktx
    implementation rootProject.ext.std_libs.androidx_constraintlayout
    implementation rootProject.ext.std_libs.androidx_documentfile
    implementation rootProject.ext.std_libs.com_google_android_material

    implementation rootProject.ext.storage_libs.com_google_crypto_tink_android

    /**
     * Storage Dependencies
     */
    implementation project(':storage:lib')

    /**
     * External Dependencies
     *
     * If the dependencies below are updated,
     * please make sure to update the prebuilt libraries and the Android.bp files
     * in the top-level `libs` folder to reflect that.
     * You can copy these libraries from ~/.gradle/caches/modules-2/files-2.1
     */
    // later versions than 2.1.1 require newer kotlin version
//    implementation "io.insert-koin:koin-core-jvm:3.2.0"
//    implementation "io.insert-koin:koin-android:3.2.0"
    implementation fileTree(include: ['*.jar'], dir: "${rootProject.rootDir}/libs/koin-android")
    implementation fileTree(include: ['*.aar'], dir: "${rootProject.rootDir}/libs/koin-android")

//    implementation "cash.z.ecc.android:kotlin-bip39:1.0.6"
    implementation fileTree(include: ['kotlin-bip39-jvm-1.0.6.jar'], dir: "${rootProject.rootDir}/libs")

    /**
     * Test Dependencies (do not concern the AOSP build)
     */
    lintChecks rootProject.ext.lint_libs.exceptions

    // anything less than 'implementation' fails tests run with gradlew
    testImplementation rootProject.ext.aosp_libs
    testImplementation 'androidx.test.ext:junit:1.1.5'
    testImplementation('org.robolectric:robolectric:4.10.3')
    testImplementation 'org.hamcrest:hamcrest:2.2'
    testImplementation "org.junit.jupiter:junit-jupiter-api:$junit5_version"
    testImplementation "org.junit.jupiter:junit-jupiter-params:$junit5_version"
    testImplementation "io.mockk:mockk:$mockk_version"
    testImplementation 'org.bitcoinj:bitcoinj-core:0.16.2'
    testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junit5_version"
    testRuntimeOnly "org.junit.vintage:junit-vintage-engine:$junit5_version"

    androidTestImplementation rootProject.ext.aosp_libs
    androidTestImplementation 'androidx.test:runner:1.4.0'
    androidTestImplementation 'androidx.test:rules:1.4.0'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation "io.mockk:mockk-android:$mockk_version"
    androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
}

apply from: "${rootProject.rootDir}/gradle/ktlint.gradle"

gradle.projectsEvaluated {
    tasks.withType(JavaCompile) {
        options.compilerArgs.add('-Xbootclasspath/p:app/libs/android.jar:app/libs/libcore.jar')
    }
}

tasks.withType(Test).configureEach {
    testLogging {
        showExceptions true
        showCauses true
        showStackTraces true

        exceptionFormat = 'full'
    }
}

configurations {
    all {
        resolutionStrategy {
            failOnNonReproducibleResolution()
        }
    }
}

tasks.register('provisionEmulator', Exec) {
    group("emulator")

    dependsOn(tasks.assembleRelease)

    doFirst {
        commandLine "${project.projectDir}/development/scripts/provision_emulator.sh",
                "seedvault",
                "system-images;android-34;google_apis;x86_64"

        environment "ANDROID_HOME", android.sdkDirectory.absolutePath
        environment "JAVA_HOME", System.properties['java.home']
    }
}

tasks.register('startEmulator', Exec) {
    group("emulator")

    doFirst {
        commandLine "${project.projectDir}/development/scripts/start_emulator.sh", "seedvault"

        environment "ANDROID_HOME", android.sdkDirectory.absolutePath
        environment "JAVA_HOME", System.properties['java.home']
    }
}

tasks.register('installEmulatorRelease', Exec) {
    group("emulator")

    dependsOn(tasks.assembleRelease)

    doFirst {
        commandLine "${project.projectDir}/development/scripts/install_app.sh"

        environment "ANDROID_HOME", android.sdkDirectory.absolutePath
        environment "JAVA_HOME", System.properties['java.home']
    }
}

tasks.register('clearEmulatorAppData', Exec) {
    group("emulator")

    doFirst {
        commandLine "${project.projectDir}/development/scripts/clear_app_data.sh"

        environment "ANDROID_HOME", android.sdkDirectory.absolutePath
        environment "JAVA_HOME", System.properties['java.home']
    }
}
