plugins {
    id "com.android.application"
    id "kotlin-android"
    id "org.jlleitschuh.gradle.ktlint" version "10.2.0"
}

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

android {
    compileSdkVersion rootProject.ext.compileSdkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion

    defaultConfig {
        minSdkVersion 29 // leave at 29 for robolectric tests
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionNameSuffix "-$gitDescribe"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        testInstrumentationRunnerArguments disableAnalytics: 'true'
    }

    buildTypes {
        release {
            minifyEnabled false
        }
    }

    lintOptions {
        disable "DialogFragmentCallbacksDetector",
                "InvalidFragmentVersionForActivityResult",
                "CheckedExceptions"
        abortOnError true
    }
    compileOptions {
        targetCompatibility 1.8
        sourceCompatibility 1.8
    }
    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_1_8.toString()
        languageVersion = "1.4"
    }
    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("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')
//    implementation fileTree(include: ['storage.aar'], dir: "${rootProject.rootDir}/storage/lib/libs")

    /**
     * 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.1.2"
//    implementation "io.insert-koin:koin-android:3.1.2"
    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.2"
    implementation fileTree(include: ['kotlin-bip39-1.0.2.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.3'
    testImplementation('org.robolectric:robolectric:4.3.1') { // 4.4 has issue with non-idle Looper
        // https://github.com/robolectric/robolectric/issues/5245
        exclude group: "com.google.auto.service", module: "auto-service"
    }
    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.15.10'
    testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junit5_version"
    testRuntimeOnly "org.junit.vintage:junit-vintage-engine:$junit5_version"

    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"
}

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

gradle.projectsEvaluated {
    tasks.withType(JavaCompile) {
        if (JavaVersion.current() >= JavaVersion.VERSION_1_9) {
            options.compilerArgs.addAll(['--release', '8'])
        }
        options.compilerArgs.add('-Xbootclasspath/p:app/libs/android.jar:app/libs/libcore.jar')
    }
}

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