import java.util.Properties

plugins {
    alias(libs.plugins.android.application)
    alias(libs.plugins.kotlin.android)
    alias(libs.plugins.kotlin.compose)
}

// Release signing is loaded from keystore.properties, which exists only on a machine
// that owns the signing key (never committed — see .gitignore). F-Droid and CI have no
// such file and build unsigned; that unsigned output is exactly what F-Droid's
// reproducible-build check compares against before re-applying our signature.
val keystorePropertiesFile = rootProject.file("keystore.properties")
val keystoreProperties =
    Properties().apply {
        if (keystorePropertiesFile.exists()) keystorePropertiesFile.inputStream().use { load(it) }
    }

android {
    namespace = "ca.ksamad.encore"
    compileSdk = 35

    // Pin the build-tools to exactly what Nix supplies. Without this, AGP picks
    // its own default version and tries to auto-install it into the read-only
    // Nix SDK, which fails. Keep this in sync with flake.nix's buildToolsVersion.
    buildToolsVersion = "35.0.0"

    defaultConfig {
        applicationId = "ca.ksamad.encore"
        minSdk = 24
        targetSdk = 35
        versionCode = 1
        versionName = "0.1.0"
    }

    signingConfigs {
        // Present only when the developer keystore is configured; absent on F-Droid/CI.
        if (keystorePropertiesFile.exists()) {
            create("release") {
                storeFile = file(keystoreProperties.getProperty("storeFile"))
                storePassword = keystoreProperties.getProperty("storePassword")
                keyAlias = keystoreProperties.getProperty("keyAlias")
                keyPassword = keystoreProperties.getProperty("keyPassword")
            }
        }
    }

    buildTypes {
        release {
            // Sign with the release key when configured; otherwise stay unsigned so
            // F-Droid can build/verify reproducibly and re-apply our signature.
            signingConfig = signingConfigs.findByName("release")

            // R8 code shrinking + resource shrinking. Critical with
            // material-icons-extended: it bundles thousands of vector icons, and
            // R8 strips everything we don't reference (debug builds can't shrink,
            // so the debug APK stays large — that's expected).
            isMinifyEnabled = true
            isShrinkResources = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro",
            )
        }
    }

    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }

    kotlinOptions {
        jvmTarget = "17"
    }

    buildFeatures {
        compose = true
    }

    testOptions {
        unitTests.all {
            // Surface `println`/stdout from unit tests in the Gradle console.
            // Handy for the gated MPD integration test (see MpdServerIntegrationTest).
            it.testLogging {
                showStandardStreams = true
            }
        }
    }
}

// --- Nix reproducible-build support -----------------------------------------
// The Nix dependency-capture step (`nixDownloadDeps`) resolves *every* resolvable
// configuration at once to record what Gradle downloads. Several AGP/Kotlin
// configurations aren't meant to be resolved that way and break the sweep:
//   * `*DependenciesMetadata` (Kotlin) resolve with no version under a BOM.
//   * the unit-/android-test classpaths carry a `:app -> :app` self-dependency
//     that is ambiguous without AGP's own artifact-view based resolution.
// These tweaks apply ONLY during that capture step, detected via the
// IN_GRADLE_UPDATE_DEPS env var the update script sets. Ordinary builds — in the
// dev shell or the real `nix build` (assembleDebug) — see none of this and use
// 100% standard Android configuration, including their own test resolution.
if (System.getenv("IN_GRADLE_UPDATE_DEPS") == "1") {
    // Drop the test components entirely for the sweep, so their compile/runtime
    // classpaths (which carry the ambiguous `:app -> :app` self-dependency) are
    // never created. Removing the component is clean; merely marking those
    // classpaths non-resolvable instead makes the Kotlin plugin fail.
    androidComponents {
        beforeVariants(selector().all()) { variantBuilder ->
            variantBuilder.enableAndroidTest = false
            variantBuilder.enableUnitTest = false
        }
    }

    // Kotlin's `*DependenciesMetadata` configs resolve with no version under a
    // BOM; they pull nothing the real classpaths don't, so skip them.
    configurations.configureEach {
        if (name.endsWith("DependenciesMetadata")) {
            isCanBeResolved = false
        }
    }

    // With the unit-test component gone, still record the test-only artifacts
    // (JUnit) via a clean configuration that has no project self-dependency, so
    // the captured lockfile is complete enough for `testDebugUnitTest` to run
    // offline during `nix build`.
    val nixCaptureTestDeps = configurations.create("nixCaptureTestDeps")
    dependencies.addProvider(nixCaptureTestDeps.name, libs.junit)
}

dependencies {
    implementation(libs.androidx.core.ktx)
    implementation(libs.androidx.lifecycle.runtime.ktx)
    implementation(libs.androidx.lifecycle.runtime.compose)
    implementation(libs.androidx.lifecycle.viewmodel.compose)
    implementation(libs.androidx.activity.compose)
    implementation(libs.kotlinx.coroutines.android)
    implementation(libs.androidx.datastore.preferences)
    implementation(libs.androidx.media)
    implementation(libs.coil.compose)

    // The Compose BOM aligns every Compose artifact to one tested version set,
    // so the individual Compose deps below are declared without versions.
    implementation(platform(libs.androidx.compose.bom))
    implementation(libs.androidx.ui)
    implementation(libs.androidx.ui.graphics)
    implementation(libs.androidx.ui.tooling.preview)
    implementation(libs.androidx.material3)
    implementation(libs.androidx.material.icons.extended)
    debugImplementation(libs.androidx.ui.tooling)

    testImplementation(libs.junit)
}
