import nerd.tuxmobil.fahrplan.congress.Android
import nerd.tuxmobil.fahrplan.congress.Compose
import nerd.tuxmobil.fahrplan.congress.Config
import nerd.tuxmobil.fahrplan.congress.Libs

ext.set("APP_VERSION", "${gitSha()}")

apply plugin: "com.android.application"
apply plugin: "kotlin-android"
apply plugin: "org.jetbrains.kotlin.plugin.compose"
apply plugin: "com.google.devtools.ksp"
apply plugin: "de.mobilej.unmock"
apply plugin: "com.getkeepsafe.dexcount"
apply from: "../gradle/sonarqube.gradle"

android {
    namespace "nerd.tuxmobil.fahrplan.congress"

    compileSdk Android.compileSdkVersion
    buildToolsVersion = Android.buildToolsVersion

    defaultConfig {
        versionCode 110
        versionName "1.72.0"
        minSdk Android.minSdkVersion
        targetSdk Android.targetSdkVersion
        base.archivesName = "Fahrplan-$versionName"

        vectorDrawables.useSupportLibrary = true // allows using fillColor, fillType, strokeColor functionalities below Android 7.0 (API 24)

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        testInstrumentationRunnerArguments runnerBuilder: "de.mannodermaus.junit5.AndroidJUnit5Builder"

        // Build information
        resValue("string", "modification_time", "\"${modificationTime()}\"")
        resValue("string", "git_sha", "\"${gitSha()}\"")

        // Build configuration / feature flags
        buildConfigField "String", "F_DROID_URL", '""'
        buildConfigField "String", "TRANSLATION_PLATFORM_URL", '"https://crowdin.com/project/eventfahrplan"'
        buildConfigField "String", "SOURCE_CODE_URL", '"https://github.com/EventFahrplan/EventFahrplan"'
        buildConfigField "String", "ISSUES_URL", '"https://github.com/EventFahrplan/EventFahrplan/issues"'
        buildConfigField "String", "DATA_PRIVACY_STATEMENT_DE_URL", '"https://github.com/EventFahrplan/EventFahrplan/blob/master/DATA-PRIVACY-DE.md"'
        buildConfigField "String", "EVENT_POSTAL_ADDRESS", '""'
        buildConfigField "boolean", "ENGAGE_C3NAV_APP_INSTALLATION", "false"
        buildConfigField "String", "C3NAV_URL", '""'
        buildConfigField "boolean", "ENABLE_ALTERNATIVE_SCHEDULE_URL", "false"
        buildConfigField "boolean", "ENABLE_CHAOSFLIX_EXPORT", "false"
        buildConfigField "boolean", "ENABLE_ENGELSYSTEM_SHIFTS", "false"
        resValue("string", "engelsystem_alias", "Engelsystem")
        resValue("string", "engelsystem_shifts_alias", "Engelshifts")
        resValue("string", "preference_hint_engelsystem_json_export_url", '""')
        buildConfigField "boolean", "SHOW_APP_DISCLAIMER", "true"
        buildConfigField "boolean", "ENGAGE_GOOGLE_BETA_TESTING", "true"
        buildConfigField "boolean", "ENGAGE_GOOGLE_PLAY_RATING", "true"
        buildConfigField "boolean", "ENGAGE_LANDSCAPE_ORIENTATION", "true"
        buildConfigField "boolean", "ENABLE_FOSDEM_ROOM_STATES", "false"
        buildConfigField "String", "FOSDEM_ROOM_STATES_URL", '""'
        buildConfigField "String", "FOSDEM_ROOM_STATES_PATH", '""'
    }

    buildFeatures {
        buildConfig true
        compose true
    }

    buildTypes {
        debug {
            resValue("string", "build_time", "\"${buildTime()}\"")
            versionNameSuffix "-DEBUG"
            applicationIdSuffix ".debug"
            debuggable true
        }
        release {
            resValue("string", "build_time", "")
            minifyEnabled true
            proguardFiles getDefaultProguardFile("proguard-android.txt"),
                    "proguard-rules/proguard-project.txt",
                    "proguard-rules/okhttp3.pro",
                    "proguard-rules/okio.pro"
        }
    }

    signingConfigs {
        cccamp2023
        ccc38c3
    }

    def defaultDimension = "default"
    flavorDimensions = [defaultDimension]

    productFlavors {
        cccamp2023 {
            dimension defaultDimension
            applicationId "info.metadude.android.cccamp.schedule"
            versionName "${defaultConfig.versionName}-CCCamp-Edition"
            buildConfigField "String", "GOOGLE_PLAY_URL", '"https://play.google.com/store/apps/details?id=info.metadude.android.cccamp.schedule"'
            buildConfigField "String", "F_DROID_URL", '"https://f-droid.org/packages/info.metadude.android.cccamp.schedule"'
            buildConfigField "String", "SCHEDULE_URL", '"https://events.ccc.de/camp/2023/hub/api/c/camp23/schedule.xml"'
            buildConfigField "String", "EVENT_URL", '"http://events.ccc.de/camp/2023/Fahrplan/events/%1$s.html"'
            buildConfigField "String", "EVENT_WEBSITE_URL", '"http://events.ccc.de/camp/2023/"'
            buildConfigField "String", "EVENT_POSTAL_ADDRESS", '"Ziegeleipark Mildenberg, 16792 Zehdenick"'
            buildConfigField "String", "SERVER_BACKEND_TYPE", '"frab"'
            buildConfigField "boolean", "SHOW_APP_DISCLAIMER", "false"
            buildConfigField "boolean", "ENGAGE_C3NAV_APP_INSTALLATION", "true"
            buildConfigField "String", "C3NAV_URL", '"https://camp23.c3nav.de/l/"'
            buildConfigField "boolean", "ENABLE_ALTERNATIVE_SCHEDULE_URL", "true"
            buildConfigField "boolean", "ENABLE_CHAOSFLIX_EXPORT", "true"
            buildConfigField "boolean", "ENABLE_ENGELSYSTEM_SHIFTS", "true"
            resValue("string", "preference_hint_engelsystem_json_export_url", '"https://engelsystem.events.ccc.de/shifts-json-export?key=YOUR_KEY"')
            buildConfigField "String", "SOCIAL_MEDIA_HASHTAGS_HANDLES", '"#camp23 #CCCamp23 #fahrplan"'
            buildConfigField "String", "TRACE_DROID_EMAIL_ADDRESS", '"tobias.preuss+camp2023@googlemail.com"'
            buildConfigField "String", "SCHEDULE_FEEDBACK_URL", '"https://frab.cccv.de/en/camp2023/public/events/%s/feedback/new"'
        }
        ccc38c3 {
            dimension defaultDimension
            applicationId "info.metadude.android.congress.schedule"
            buildConfigField "String", "GOOGLE_PLAY_URL", '"https://play.google.com/store/apps/details?id=info.metadude.android.congress.schedule"'
            buildConfigField "String", "F_DROID_URL", '"https://f-droid.org/packages/info.metadude.android.congress.schedule"'
            buildConfigField "String", "SCHEDULE_URL", '"https://api.events.ccc.de/congress/2024/schedule.xml"'
            buildConfigField "String", "EVENT_URL", '""'
            buildConfigField "String", "EVENT_WEBSITE_URL", '"https://events.ccc.de/congress/2024/"'
            buildConfigField "String", "EVENT_POSTAL_ADDRESS", '"Congressplatz 1, 20355 Hamburg"'
            buildConfigField "String", "SERVER_BACKEND_TYPE", '"frab"'
            buildConfigField "boolean", "SHOW_APP_DISCLAIMER", "false"
            buildConfigField "boolean", "ENGAGE_C3NAV_APP_INSTALLATION", "true"
            buildConfigField "String", "C3NAV_URL", '"https://38c3.c3nav.de/l/"'
            buildConfigField "boolean", "ENABLE_ALTERNATIVE_SCHEDULE_URL", "true"
            buildConfigField "boolean", "ENABLE_CHAOSFLIX_EXPORT", "true"
            buildConfigField "boolean", "ENABLE_ENGELSYSTEM_SHIFTS", "true"
            resValue("string", "preference_hint_engelsystem_json_export_url", '"https://engel.events.ccc.de/shifts-json-export?key=YOUR_KEY"')
            buildConfigField "String", "SOCIAL_MEDIA_HASHTAGS_HANDLES", '"#38c3 #fahrplan"'
            buildConfigField "String", "TRACE_DROID_EMAIL_ADDRESS", '"tobias.preuss+38c3@googlemail.com"'
            buildConfigField "String", "SCHEDULE_FEEDBACK_URL", '""'
        }
    }

    productFlavors.configureEach { flavor ->
        if (hasSigningConfig(flavor.name)) {
            setSigningConfig(flavor)
        }
    }

    lint {
        checkDependencies true
        // for okio - https://github.com/square/okio/issues/58
        warning "InvalidPackage"
        warning "MissingDefaultResource"
    }

    compileOptions {
        targetCompatibility Config.compatibleJavaVersion
        sourceCompatibility Config.compatibleJavaVersion
    }

    kotlinOptions {
        jvmTarget = Config.compatibleJavaVersion
        freeCompilerArgs = [
                "-opt-in=kotlin.RequiresOptIn"
        ]
    }

    packagingOptions {
        resources {
            excludes += [
                    "META-INF/LICENSE.md",
                    "META-INF/LICENSE-notice.md",
            ]
        }
    }

}

unMock {
    keepStartingWith "libcore."
    keepStartingWith "org.ccil.cowan.tagsoup."
    keep "android.content.ComponentName"
    keep "android.content.ContentValues"
    keep "android.content.Intent"
    keep "android.net.Uri"
    keepStartingWith "android.text."
    keep "android.os.Bundle"
    keep "android.util.Patterns"
    keep "com.android.internal.util.ArrayUtils"
    keepAndRename "java.nio.charset.Charsets" to "xjava.nio.charset.Charsets"
}

gradle.projectsEvaluated {
    tasks.withType(JavaCompile).configureEach {
        options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
    }
}

dependencies {
    implementation project(":commons")
    implementation project(":database")
    implementation project(":network")

    def composeBom = platform(Compose.bom)
    implementation composeBom

    // Android Studio preview support
    implementation Compose.uiToolingPreview
    debugImplementation Compose.uiTooling

    implementation Compose.material

    implementation Libs.activityCompose
    implementation Libs.appCompat
    implementation Libs.betterLinkMovementMethod
    implementation Libs.constraintLayout
    implementation Libs.coreKtx
    implementation Libs.emailIntentBuilder
    implementation Libs.engelsystem
    implementation Libs.fragmentCompose
    implementation Libs.htmlConverter
    implementation Libs.kotlinCoroutinesAndroid
    implementation Libs.kotlinCoroutinesCore
    implementation Libs.lifecycleViewModel
    implementation Libs.markdownRender
    implementation Libs.material
    implementation Libs.moshi
    ksp Libs.moshiCodeGen
    implementation Libs.okhttp
    implementation Libs.okhttpLoggingInterceptor
    implementation Libs.preference
    implementation Libs.roomStates
    implementation Libs.snackengagePlayrate
    implementation Libs.tracedroid

    testImplementation project(":commons-testing")
    testImplementation Libs.annotation
    testImplementation Libs.coreTesting
    testImplementation Libs.junitJupiterApi
    testRuntimeOnly Libs.junitJupiterEngine
    testRuntimeOnly Libs.junitPlatformLauncher
    testImplementation Libs.junitJupiterParams
    testImplementation(Libs.kotlinCoroutinesTest) {
        // workaround for https://github.com/Kotlin/kotlinx.coroutines/issues/2023
        exclude group: "org.jetbrains.kotlinx", module: "kotlinx-coroutines-debug"
    }
    testImplementation Libs.threeTenBp
    testImplementation Libs.truth
    testImplementation Libs.turbine

    unmock Libs.robolectric

    androidTestImplementation Libs.androidTestCore
    androidTestRuntimeOnly Libs.androidTestRunner
    androidTestImplementation Libs.junitJupiterApi
    androidTestImplementation Libs.junitJupiterParams
    androidTestImplementation Libs.truth
}

def gitSha() {
    def res = "git rev-parse --short HEAD".execute([], project.rootDir).text.trim()
    def diff = "git diff".execute([], project.rootDir).text.trim()
    if (diff != null && diff.length() > 0) {
        res += "-dirty"
    }
    return res
}

def modificationTime() {
    // https://reproducible-builds.org/docs/source-date-epoch/
    // Set based on the current commit that is being built.
    def committedAt = System.getenv('SOURCE_DATE_EPOCH')
    if (committedAt == null || committedAt.length() == 0) {
        committedAt = "git log -1 --format=%ct".execute([], project.rootDir).text.trim()
    }
    return getFormattedDate(new Date(Long.parseLong(committedAt) * 1000))
}

static def buildTime() {
    return getFormattedDate(new Date())
}

static def getFormattedDate(Date date) {
    return date.format("yyyy-MM-dd'T'HH:mm'Z'", TimeZone.getTimeZone("UTC"))
}

def hasSigningConfig(String flavor) {
    return project.hasProperty("signing.$flavor-release.keystoreFilePath") &&
            project.hasProperty("signing.$flavor-release.keystorePassword") &&
            project.hasProperty("signing.$flavor-release.keyAlias") &&
            project.hasProperty("signing.$flavor-release.keyPassword")
}

def setSigningConfig(flavor) {
    def flavorName = flavor.name
    def props = project.getProperties()

    def signingConfig = android.signingConfigs[flavorName]
    signingConfig.storeFile file(props["signing.$flavorName-release.keystoreFilePath"])
    signingConfig.storePassword props["signing.$flavorName-release.keystorePassword"]
    signingConfig.keyAlias props["signing.$flavorName-release.keyAlias"]
    signingConfig.keyPassword props["signing.$flavorName-release.keyPassword"]

    flavor.signingConfig = signingConfig
}
