//! `build.gradle.kts` emitter — full Android library project with
//! maven-publish, ktlint hooks, and bundled-Java-facade source set wiring.

use alef_core::config::ResolvedCrateConfig;
use alef_core::template_versions::{maven, toolchain};

use crate::naming::{aar_artifact_id, aar_group_id, compile_sdk, jvm_target, min_sdk, namespace};

/// Emit `build.gradle.kts` for the generated AAR module.
///
/// Note on plugin compatibility: AGP 8.x requires an explicit
/// `kotlin("android")` plugin application, while AGP 9.0+ ships with
/// built-in Kotlin support and rejects re-application of
/// `org.jetbrains.kotlin.android`. The emitted file targets AGP 8.x
/// (the currently-pinned template version); if the AGP pin is moved
/// to 9.0+, this emitter must drop the `kotlin("android")` line.
pub fn emit(config: &ResolvedCrateConfig) -> String {
    let kotlin_version = maven::KOTLIN_JVM_PLUGIN;
    let android_gradle_plugin = maven::ANDROID_GRADLE_PLUGIN;
    let junit_legacy = maven::JUNIT_LEGACY;
    let androidx_junit = maven::ANDROIDX_TEST_EXT_JUNIT;
    let espresso_core = maven::ANDROIDX_TEST_ESPRESSO_CORE;
    let ktlint_gradle_plugin = maven::KTLINT_GRADLE_PLUGIN;
    let ktlint_version = maven::KTLINT;
    let gradle_versions_plugin = maven::GRADLE_VERSIONS_PLUGIN;
    let kotlinx_coroutines = maven::KOTLINX_COROUTINES_CORE;
    let jackson = maven::JACKSON;
    let _ = toolchain::ANDROID_JVM_TARGET;

    let android_namespace = namespace(config);
    let compile_sdk_val = compile_sdk(config);
    let min_sdk_val = min_sdk(config);
    let android_jvm_target = jvm_target(config);
    let group_id = aar_group_id(config);
    let artifact_id = aar_artifact_id(config);
    let resolved_version = config.resolved_version().unwrap_or_else(|| "0.0.0".to_string());
    let version_placeholder = resolved_version.as_str();

    format!(
        r#"// Generated by alef. Do not edit by hand.

import org.jetbrains.kotlin.gradle.dsl.JvmTarget

plugins {{
    id("com.android.library") version "{android_gradle_plugin}"
    kotlin("android") version "{kotlin_version}"
    id("maven-publish")
    id("org.jlleitschuh.gradle.ktlint") version "{ktlint_gradle_plugin}"
    id("com.github.ben-manes.versions") version "{gradle_versions_plugin}"
}}

android {{
    namespace = "{android_namespace}"
    compileSdk = {compile_sdk_val}

    defaultConfig {{
        minSdk = {min_sdk_val}
        consumerProguardFiles("consumer-rules.pro")
    }}

    compileOptions {{
        sourceCompatibility = JavaVersion.VERSION_{android_jvm_target}
        targetCompatibility = JavaVersion.VERSION_{android_jvm_target}
    }}

    sourceSets {{
        getByName("main") {{
            jniLibs.srcDirs("src/main/jniLibs")
        }}
    }}

    publishing {{
        singleVariant("release") {{
            withSourcesJar()
        }}
    }}
}}

kotlin {{
    compilerOptions {{
        jvmTarget.set(JvmTarget.JVM_{android_jvm_target})
    }}
}}

ktlint {{
    version.set("{ktlint_version}")
    android.set(true)
    ignoreFailures.set(false)
}}

dependencies {{
    implementation("org.jetbrains.kotlin:kotlin-stdlib")
    // Generated Kotlin facade uses suspend functions and Flow wrappers, both of
    // which require kotlinx-coroutines-android (transitively pulls -core).
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:{kotlinx_coroutines}")
    // Generated sealed-class DTOs use Jackson @JsonDeserialize for polymorphic
    // serde-tagged unions; jackson-module-kotlin is required for Kotlin
    // data-class deserialization (handles nullable, default values, etc.).
    // jackson-datatype-jdk8 is required because the generated DefaultClient.kt
    // registers Jdk8Module for Optional<T> / java.util.Optional support.
    implementation("com.fasterxml.jackson.core:jackson-databind:{jackson}")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin:{jackson}")
    implementation("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:{jackson}")
    testImplementation("junit:junit:{junit_legacy}")
    androidTestImplementation("androidx.test.ext:junit:{androidx_junit}")
    androidTestImplementation("androidx.test.espresso:espresso-core:{espresso_core}")
}}

publishing {{
    publications {{
        register<MavenPublication>("release") {{
            afterEvaluate {{
                from(components["release"])
            }}
            groupId = "{group_id}"
            artifactId = "{artifact_id}"
            version = "{version_placeholder}"
        }}
    }}
}}
"#
    )
}
