import java.util.Properties

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

val keystoreProps = Properties().apply {
    rootProject.file("keystore.properties").takeIf { it.exists() }
        ?.reader()?.use { load(it) }
}

android {
    namespace = "de.ladkau.schwertundmagieonpebblecompanionapp"
    compileSdk {
        version = release(36) {
            minorApiLevel = 1
        }
    }

    ndkVersion = "30.0.14904198"

    defaultConfig {
        applicationId = "de.ladkau.schwertundmagieonpebblecompanionapp"
        minSdk = 24
        targetSdk = 36
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

        ndk {
            abiFilters += listOf("arm64-v8a", "x86_64")
        }
        externalNativeBuild {
            cmake {
                arguments("-DANDROID_STL=c++_shared")
                // HAVE_VICE_SRC is detected automatically by CMakeLists.txt
                // based on whether vice-libs/<abi>/libvice.a exists.
            }
        }
    }

    signingConfigs {
        create("release") {
            keystoreProps["storeFile"]?.let { storeFile = rootProject.file(it as String) }
            storePassword = keystoreProps["storePassword"] as String?
            keyAlias      = keystoreProps["keyAlias"]     as String?
            keyPassword   = keystoreProps["keyPassword"]  as String?
        }
    }

    buildTypes {
        release {
            signingConfig = signingConfigs.getByName("release")
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }
    externalNativeBuild {
        cmake {
            path = file("src/main/jni/CMakeLists.txt")
            version = "3.22.1"
        }
    }
}

// ---------------------------------------------------------------------------
// VICE cross-compilation task
//
// Runs automatically before any CMake build step.
// Skipped entirely if vice-libs/<abi>/libvice.a already exists.
// The tarball at <project>/res/vice-3.8.tar.gz is unpacked by build_vice.sh.
// ---------------------------------------------------------------------------

val viceLibArm   = layout.projectDirectory.file("src/main/jni/vice-libs/arm64-v8a/libvice.a")
val viceLibX86   = layout.projectDirectory.file("src/main/jni/vice-libs/x86_64/libvice.a")
val viceTarball  = layout.projectDirectory.file("../res/vice-3.8.tar.gz")

tasks.register("buildVice") {
    group = "build"
    description = "Cross-compile VICE 3.8 headless for Android (ARM64 + x86_64)"

    inputs.file(viceTarball)
    outputs.file(viceLibArm)
    outputs.file(viceLibX86)

    doLast {
        if (viceLibArm.asFile.exists() && viceLibX86.asFile.exists()) {
            logger.lifecycle("VICE already built — skipping")
            return@doLast
        }

        val localProps = Properties().apply {
            rootProject.file("local.properties").takeIf { it.exists() }
                ?.reader()?.use { load(it) }
        }
        val sdkDir = localProps.getProperty("sdk.dir")
            ?: System.getenv("ANDROID_HOME")
            ?: ""
        val ndkPath = localProps.getProperty("ndk.dir")
            ?: System.getenv("ANDROID_NDK_HOME")
            ?: System.getenv("ANDROID_NDK_ROOT")
            ?: System.getenv("NDK")
            ?: sdkDir.takeIf { it.isNotEmpty() }?.let { sdk ->
                // NDK side-by-side: pick the first installed version
                file("$sdk/ndk").takeIf { it.isDirectory }
                    ?.listFiles()?.sorted()?.lastOrNull()?.absolutePath
                    ?: "$sdk/ndk-bundle".takeIf { file("$sdk/ndk-bundle").isDirectory }
            }
            ?: throw GradleException(
                "Android NDK not found.\n" +
                "Install via: Android Studio → SDK Manager → SDK Tools → NDK (Side by side)"
            )
        logger.lifecycle("Building VICE with NDK at $ndkPath …")

        val proc = ProcessBuilder("bash", "build_vice.sh")
            .directory(layout.projectDirectory.dir("src/main/jni").asFile)
            .redirectErrorStream(true)
            .also { it.environment()["NDK"] = ndkPath }
            .start()
        proc.inputStream.bufferedReader().forEachLine { logger.lifecycle(it) }
        val exit = proc.waitFor()
        if (exit != 0) throw GradleException("build_vice.sh failed (exit $exit)")

        // Touch CMakeLists.txt so CMake re-evaluates the EXISTS check on the
        // next build and picks up the newly created libvice.a.
        layout.projectDirectory.file("src/main/jni/CMakeLists.txt")
            .asFile.setLastModified(System.currentTimeMillis())
        logger.lifecycle("VICE build complete — CMakeLists.txt touched for re-evaluation")
    }
}

// ---------------------------------------------------------------------------
// nibtools cross-compilation task
//
// Builds nibconv (NIB/NBZ -> G64/D64 disk image conversion, used by the
// "Download Disks" feature) the same way buildVice builds VICE above.
// Skipped entirely if nibtools-libs/<abi>/libnibtools.a already exists.
// The tarball at <project>/res/nibtools-91344e0ee3.tar.gz is unpacked by
// build_nibtools.sh.
// ---------------------------------------------------------------------------

val nibtoolsLibArm  = layout.projectDirectory.file("src/main/jni/nibtools-libs/arm64-v8a/libnibtools.a")
val nibtoolsLibX86  = layout.projectDirectory.file("src/main/jni/nibtools-libs/x86_64/libnibtools.a")
val nibtoolsTarball = layout.projectDirectory.file("../res/nibtools-91344e0ee3.tar.gz")

tasks.register("buildNibtools") {
    group = "build"
    description = "Cross-compile nibtools' nibconv for Android (ARM64 + x86_64)"

    inputs.file(nibtoolsTarball)
    outputs.file(nibtoolsLibArm)
    outputs.file(nibtoolsLibX86)

    doLast {
        if (nibtoolsLibArm.asFile.exists() && nibtoolsLibX86.asFile.exists()) {
            logger.lifecycle("nibtools already built — skipping")
            return@doLast
        }

        val localProps = Properties().apply {
            rootProject.file("local.properties").takeIf { it.exists() }
                ?.reader()?.use { load(it) }
        }
        val sdkDir = localProps.getProperty("sdk.dir")
            ?: System.getenv("ANDROID_HOME")
            ?: ""
        val ndkPath = localProps.getProperty("ndk.dir")
            ?: System.getenv("ANDROID_NDK_HOME")
            ?: System.getenv("ANDROID_NDK_ROOT")
            ?: System.getenv("NDK")
            ?: sdkDir.takeIf { it.isNotEmpty() }?.let { sdk ->
                file("$sdk/ndk").takeIf { it.isDirectory }
                    ?.listFiles()?.sorted()?.lastOrNull()?.absolutePath
                    ?: "$sdk/ndk-bundle".takeIf { file("$sdk/ndk-bundle").isDirectory }
            }
            ?: throw GradleException(
                "Android NDK not found.\n" +
                "Install via: Android Studio → SDK Manager → SDK Tools → NDK (Side by side)"
            )
        logger.lifecycle("Building nibtools with NDK at $ndkPath …")

        val proc = ProcessBuilder("bash", "build_nibtools.sh")
            .directory(layout.projectDirectory.dir("src/main/jni").asFile)
            .redirectErrorStream(true)
            .also { it.environment()["NDK"] = ndkPath }
            .start()
        proc.inputStream.bufferedReader().forEachLine { logger.lifecycle(it) }
        val exit = proc.waitFor()
        if (exit != 0) throw GradleException("build_nibtools.sh failed (exit $exit)")

        layout.projectDirectory.file("src/main/jni/CMakeLists.txt")
            .asFile.setLastModified(System.currentTimeMillis())
        logger.lifecycle("nibtools build complete — CMakeLists.txt touched for re-evaluation")
    }
}

// Run buildVice and buildNibtools before any CMake configure or build step.
tasks.whenTaskAdded {
    if (name.startsWith("configureCMake") || name.startsWith("buildCMake") ||
        name.startsWith("externalNativeBuild")) {
        dependsOn("buildVice")
        dependsOn("buildNibtools")
    }
}

// Note: C64/1541 ROMs are intentionally NOT bundled into the APK — they are
// copyrighted Commodore firmware. The app prompts the user to import their
// own ROM dump at runtime instead (see MainActivity.showRomImportDialog()).
// res/extract_roms.sh remains available for extracting ROMs from the VICE
// tarball locally (e.g. to sideload onto a test device), but nothing in this
// build copies them into assets/ or the APK.

dependencies {
    implementation(libs.androidx.activity.ktx)
    implementation(libs.androidx.appcompat)
    implementation(libs.androidx.constraintlayout)
    implementation(libs.androidx.core.ktx)
    implementation(libs.material)
    implementation(libs.nanohttpd)
    implementation(libs.androidx.documentfile)
    testImplementation(libs.junit)
    androidTestImplementation(libs.androidx.espresso.core)
    androidTestImplementation(libs.androidx.junit)
}
