import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.gradle.process.ExecOperations
import org.gradle.kotlin.dsl.support.serviceOf

plugins {
    alias(libs.plugins.kotlinMultiplatform)
    alias(libs.plugins.androidApplication)
}

kotlin {
    // 让 Kotlin 使用 JDK 17 运行编译任务
    jvmToolchain(17)
    androidTarget()

    ohosArm64 {
        compilations.getByName("main") {
            cinterops {
                val sample by creating {
                    defFile(project.file("src/nativeInterop/cinterop/sample.def"))
                    includeDirs(project.file("src/nativeInterop/cinterop/include"))
                    compilerOpts("-I${project.projectDir}/src/nativeInterop/cinterop/include")
                }
            }
        }
        binaries {
            sharedLib {
                baseName = "kn"
                // outputDirectory = file("customer-output")
                // outputFile 是只读属性，由 outputDirectory 和 baseName 决定
                // println("Output file path: ${outputFile.absolutePath}")
                freeCompilerArgs += listOf("-Xbinary=sanitizer=address", "-Xbinary=splitBCfile=1")
                // 链接静态库目录和库名，使用 --whole-archive 强制包含静态库所有符号
                linkerOpts("-L${project.projectDir}/native-libs/ohosArm64", "--whole-archive", "-lsample", "--no-whole-archive")
//                export(project(":lib-arith")) {
//                    transitiveExport = false
//                }
            }
            staticLib {
                baseName = "kn"
                linkerOpts("-L${project.projectDir}/native-libs/ohosArm64", "--whole-archive", "-lsample", "--no-whole-archive")
            }
        }
    }

    listOf(
        iosArm64(),
        iosSimulatorArm64()
    ).forEach { iosTarget ->
        iosTarget.binaries.framework {
            baseName = "ComposeApp"
            isStatic = true
        }
    }

    sourceSets {
        val commonMain by getting
        val iosMain by creating {
            dependsOn(commonMain)
            dependencies {
                implementation(project(":lib-arith"))
            }
        }

        val iosSimulatorArm64Main by getting {
            dependsOn(iosMain)
        }

        val ohosMain by creating {
            dependsOn(commonMain)
            dependencies {
                api(project(":lib-arith"))
                implementation(project(":lib-analytics"))
            }
        }

        val ohosArm64Main by getting {
            dependsOn(ohosMain)
        }

        androidMain.dependencies {
            implementation(libs.androidx.activity.compose)
            implementation(project(":lib-arith"))
        }
        commonMain.dependencies {

        }
        commonTest.dependencies {
            implementation(libs.kotlin.test)
        }
    }
}

android {
    namespace = "com.example.kotlin_sample"
    compileSdk = libs.versions.android.compileSdk.get().toInt()

    defaultConfig {
        applicationId = "com.kotlin_sample.kotlin_sample"
        minSdk = libs.versions.android.minSdk.get().toInt()
        targetSdk = libs.versions.android.targetSdk.get().toInt()
        versionCode = 1
        versionName = "1.0"
    }
    packaging {
        resources {
            excludes += "/META-INF/{AL2.0,LGPL2.1}"
        }
    }
    buildTypes {
        getByName("release") {
            isMinifyEnabled = false
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_11
        targetCompatibility = JavaVersion.VERSION_11
    }
}

dependencies {
    // 移除 Compose 调试工具
}

// 构建示例静态库（arm64）
val buildSampleStaticLib by tasks.registering {
    group = "native"
    description = "Build sample static library (.a) for ohosArm64"
    
    val projectDir = project.projectDir
    val projectDirPath = projectDir.absolutePath
    val includeDir = "$projectDirPath/native-libs/sample/include"
    val outDir = "$projectDirPath/native-libs/ohosArm64"
    val staticLibPath = "$outDir/libsample.a"
    val srcDirPath = "$projectDirPath/native-libs/sample/src"
    
    val outDirFile = File(outDir)
    val staticLibFile = File(staticLibPath)
    val srcDirFile = File(srcDirPath)
    
    val konanUserDir = System.getProperty("user.home") + "/.konan"
    val konanDependenciesDir = File("$konanUserDir/dependencies")
    
    val execOps = project.serviceOf<ExecOperations>()

    doLast {
        val objFileToDelete = File("$outDir/sample.o")
        outDirFile.mkdirs()
        if (staticLibFile.exists()) {
            staticLibFile.delete()
        }
        if (objFileToDelete.exists()) {
            objFileToDelete.delete()
        }

        // 查找 Kotlin Native 下载的 LLVM 工具链
        val llvmDir = konanDependenciesDir.listFiles()?.firstOrNull {
            it.name.startsWith("llvm-") && it.name.contains("ohos")
        } ?: throw GradleException("Kotlin Native LLVM toolchain for OHOS not found in ${konanDependenciesDir.absolutePath}")

        val isWindows = org.apache.tools.ant.taskdefs.condition.Os.isFamily(org.apache.tools.ant.taskdefs.condition.Os.FAMILY_WINDOWS)
        val exeSuffix = if (isWindows) ".exe" else ""

        // 动态查找 Clang 编译器：优先找带 ohos 前缀的，否则找通用的 clang
        val binDir = File(llvmDir, "bin")
        val clangExecutable = binDir.listFiles()?.firstOrNull {
            it.name.startsWith("aarch64-") && it.name.contains("ohos") && it.name.endsWith("clang$exeSuffix")
        } ?: File(binDir, "clang$exeSuffix")

        val arExecutable = File(binDir, "llvm-ar$exeSuffix")

        if (!clangExecutable.exists()) {
            throw GradleException("Clang compiler not found at ${clangExecutable.absolutePath}")
        }

        println("Host OS: ${System.getProperty("os.name")}")
        println("Using clang: ${clangExecutable.absolutePath}")
        println("Using ar: ${arExecutable.absolutePath}")

        val objectFiles = mutableListOf<String>()
        // 编译 .c 和 .S 文件
        srcDirFile.listFiles { _, name -> name.endsWith(".c") || name.endsWith(".S") }?.forEach { srcFile ->
            val objFile = "$outDir/${srcFile.nameWithoutExtension}.o"
            val objFileFile = File(objFile)
            if (objFileFile.exists()) {
                objFileFile.delete()
            }
            println("Compiling ${srcFile.name}...")
            execOps.exec {
                // 使用 OHOS SDK clang 编译，它会自动处理 target 和 sysroot
                commandLine(clangExecutable.absolutePath, "-c", "-fPIC", "-O2", "-I", includeDir, srcFile.absolutePath, "-o", objFile)
            }
            objectFiles.add(objFile)
        }

        if (objectFiles.isEmpty()) {
            throw GradleException("No source files (.c, .S) found in $srcDirPath")
        }

        execOps.exec {
            // 使用 llvm-ar 创建 archive，确保格式兼容 lld
            commandLine(listOf(arExecutable.absolutePath, "rcs", staticLibPath) + objectFiles)
        }
    }
}

arrayOf("debug", "release").forEach { type ->
    val capitalizedType = type.replaceFirstChar { it.uppercase() }
    tasks.register<Copy>("publish${capitalizedType}BinariesToHarmonyApp") {
        group = "harmony"
        dependsOn("link${capitalizedType}SharedOhosArm64")
        into(rootProject.file("harmonyApp"))
        val binaryPath = "build/bin/ohosArm64/${type}Shared"
        val binaryDir = file(binaryPath)
        from("$binaryPath/libkn_api.h") {
            into("entry/src/main/cpp/include/")
        }
        from("$binaryPath/libkn.so") {
            into("entry/libs/arm64-v8a/")
        }
        from("native-libs/ohosArm64/libsample.a") {
            into("entry/src/main/cpp/libs/")
        }
        doFirst {
            if (!binaryDir.exists()) {
                throw GradleException("未找到产物目录: ${binaryDir.absolutePath}")
            }
        }
    }
    tasks.named("link${capitalizedType}SharedOhosArm64").configure {
        dependsOn(buildSampleStaticLib)
    }
}
