/*
 * This file was generated by the Gradle "init" task.
 *
 * This generated file contains a sample Java Library project to get you started.
 * For more details take a look at the Java Libraries chapter in the Gradle
 * User Manual available at https://docs.gradle.org/6.3/userguide/java_library_plugin.html
 */
import com.android.build.gradle.internal.tasks.BaseTask
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.internal.ensureParentDirsCreated
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.util.Base64

plugins {
	kotlin("android")
	kotlin("plugin.serialization")
	id("com.github.gmazzo.buildconfig")

	id("com.android.application") version "8.13.2"
	id("org.ajoberstar.grgit")
}

kotlin {
	jvmToolchain {
		languageVersion.set(JavaLanguageVersion.of(17))
	}
}
java {
	toolchain {
		languageVersion.set(JavaLanguageVersion.of(17))
	}
}

val copyGuiAssets = tasks.register<Copy>("copyGuiAssets") {
	val target = layout.projectDirectory.dir("src/main/assets/web-gui")
	delete(target)
	from(rootProject.layout.projectDirectory.dir("gui/out/renderer"))
	into(target)
	if (inputs.sourceFiles.isEmpty) {
		throw GradleException("You need to run \"pnpm run build\" on the gui folder first!")
	}
}
tasks.preBuild {
	dependsOn(copyGuiAssets)
}

// Set up signing pre/post tasks
val preSign = tasks.register("preSign") {
	dependsOn(writeTempKeyStore)
}
val postSign = tasks.register("postSign") {
	finalizedBy(deleteTempKeyStore)
}
tasks.withType<BaseTask> {
	dependsOn(preSign)
	finalizedBy(postSign)
}

// Handle GitHub secret Android KeyStore files
val envKeyStore: String? = System.getenv("ANDROID_STORE_FILE")?.takeIf { it.isNotBlank() }
val tempKeyStore = project.layout.buildDirectory.file("tmp/keystore.tmp.jks").get().asFile
val writeTempKeyStore = tasks.register("writeTempKeyStore") {
	if (envKeyStore != null) {
		doLast {
			tempKeyStore.apply {
				ensureParentDirsCreated()
				tempKeyStore.writeBytes(Base64.getDecoder().decode(envKeyStore))
				tempKeyStore.deleteOnExit()
			}
		}
		finalizedBy(deleteTempKeyStore)
	} else {
		enabled = false
	}
}
val deleteTempKeyStore = tasks.register<Delete>("deleteTempKeyStore") {
	if (envKeyStore != null) {
		delete(tempKeyStore)
	} else {
		enabled = false
	}
}

tasks.withType<KotlinCompile> {
	compilerOptions {
		jvmTarget.set(JvmTarget.JVM_17)
		freeCompilerArgs.set(listOf("-Xvalue-classes"))
	}
}

// Set compiler to use UTF-8
tasks.withType<JavaCompile> {
	options.encoding = "UTF-8"
}
tasks.withType<Test> {
	systemProperty("file.encoding", "UTF-8")
}
tasks.withType<Javadoc> {
	options.encoding = "UTF-8"
}

repositories {
	google()
}

dependencies {
	implementation(project(":server:core"))

	implementation("commons-cli:commons-cli:1.11.0")
	implementation("org.apache.commons:commons-lang3:3.20.0")

	// Android stuff
	implementation("androidx.appcompat:appcompat:1.7.1")
	implementation("androidx.core:core-ktx:1.17.0")
	implementation("com.google.android.material:material:1.13.0")
	implementation("androidx.constraintlayout:constraintlayout:2.2.1")
	implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
	androidTestImplementation("androidx.test.ext:junit:1.3.0")
	androidTestImplementation("androidx.test.espresso:espresso-core:3.7.0")

	// Serial
	implementation("com.github.mik3y:usb-serial-for-android:3.7.0")
}

// The android block is where you configure all your Android-specific build options.
extra.apply {
	set("gitVersionCode", grgit.tag.list().size)
	set("gitVersionName", grgit.describe(mapOf("tags" to true, "always" to true)))
}
android {
	// The app's namespace. Used primarily to access app resources.

	namespace = "dev.slimevr.android"

	/* compileSdk specifies the Android API level Gradle should use to
		compile your app. This means your app can use the API features included in
		this API level and lower. */

	compileSdk = 36

	/* The defaultConfig block encapsulates default settings and entries for all
		build variants and can override some attributes in main/AndroidManifest.xml
		dynamically from the build system. You can configure product flavors to override
		these values for different versions of your app. */

	packaging {
		resources.excludes.add("META-INF/*")
	}

	defaultConfig {

		// Uniquely identifies the package for publishing.
		applicationId = "dev.slimevr.server.android"

		// Defines the minimum API level required to run the app.
		minSdk = 26

		// Specifies the API level used to test the app.
		targetSdk = 36

		// adds an offset of the version code as we might do apk releases in the middle of actual
		// releases if we failed on bundling or stuff
		val versionCodeOffset = 5
		// Defines the version number of your app.
		versionCode = (extra["gitVersionCode"] as? Int)?.plus(versionCodeOffset) ?: 0

		// Defines a user-friendly version name for your app.
		versionName = extra["gitVersionName"] as? String ?: "v0.0.0"

		logger.lifecycle("i: Configured for SlimeVR Android version \"$versionName\" ($versionCode).")

		testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
	}

	signingConfigs {
		val inputKeyStore: File? = if (envKeyStore != null) {
			logger.lifecycle("i: \"ANDROID_STORE_FILE\" environment variable found, using for signing config.")
			tempKeyStore
		} else {
			file("secrets/keystore.jks").takeIf { it.canRead() && it.length() > 0 }
		}

		if (inputKeyStore != null) {
			logger.info("i: Configuring signing for Android KeyStore file: \"${inputKeyStore.path}\".")

			create("release") {
				storeFile = inputKeyStore
				storePassword = System.getenv("ANDROID_STORE_PASSWD")
				keyAlias = System.getenv("ANDROID_KEY_ALIAS") ?: "key0"
				keyPassword = System.getenv("ANDROID_KEY_PASSWD")
			}
		} else {
			logger.warn("w: Android KeyStore file is not valid or not found, skipping signing.")
		}
	}

	/*	The buildTypes block is where you can configure multiple build types.
		By default, the build system defines two build types: debug and release. The
		debug build type is not explicitly shown in the default build configuration,
		but it includes debugging tools and is signed with the debug key. The release
		build type applies ProGuard settings and is not signed by default. */

	buildTypes {

		/*	By default, Android Studio configures the release build type to enable code
			shrinking, using minifyEnabled, and specifies the default ProGuard rules file. */

		release {
			isMinifyEnabled = true // Enables code shrinking for the release build type.
			isShrinkResources = true // Enables resource shrinking.
			proguardFiles(
				getDefaultProguardFile("proguard-android-optimize.txt"),
				"proguard-rules.pro",
			)
			signingConfig = signingConfigs.findByName("release")
		}
	}

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