import groovy.xml.XmlUtil

plugins {
    id "com.android.application"
    id "kotlin-android"
    id "org.jlleitschuh.gradle.ktlint" version "9.4.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 "CheckedExceptions"
        abortOnError true
    }
    compileOptions {
        targetCompatibility 1.8
        sourceCompatibility 1.8
    }
    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_1_8.toString()
        languageVersion = "1.3"
    }
    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_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
     */
    // later versions than 2.1.1 require newer kotlin version
    implementation fileTree(include: ['*.jar'], dir: "${rootProject.rootDir}/libs/koin-android")
    implementation fileTree(include: ['*.aar'], dir: "${rootProject.rootDir}/libs/koin-android")

    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.2'
    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.3.0'
    androidTestImplementation 'androidx.test:rules:1.3.0'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    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')
    }
}

// http://www.31mins.com/android-studio-build-system-application/
preBuild.doLast {
    def imlFile = file(project.name + ".iml")

    try {
        def parsedXml = (new XmlParser()).parse(imlFile)
        def jdkNode = parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' }
        parsedXml.component[1].remove(jdkNode)

        def apiString = android.compileSdkVersion.substring("android-".length())
        def sdkString = "Android API " + apiString + " Platform"
        //noinspection GroovyResultOfObjectAllocationIgnored // the note gets inserted
        new Node(parsedXml.component[1], 'orderEntry', [
                'type'   : 'jdk',
                'jdkName': sdkString,
                'jdkType': 'Android SDK'
        ])
        XmlUtil.serialize(parsedXml, new FileOutputStream(imlFile))

    } catch (NullPointerException | FileNotFoundException ex) {
        ex.printStackTrace()
    }
}

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