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 {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }
    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_11.toString()
        languageVersion = "1.6"
    }
    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')

    /**
     * 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.8.1') {
        // https://github.com/robolectric/robolectric/issues/5245
        exclude group: "com.google.auto.service", module: "auto-service"
    }
    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.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) {
        options.compilerArgs.add('-Xbootclasspath/p:app/libs/android.jar:app/libs/libcore.jar')
    }
}

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