@file:OptIn(ExperimentalNativeApi::class, ExperimentalForeignApi::class)

package com.example.kotlin_sample

import kotlinx.cinterop.ExperimentalForeignApi
import kotlin.experimental.ExperimentalNativeApi
import com.example.arith.Arith
import com.example.analytics.analyticsInfo
import kotlinx.cinterop.*
import platform.posix.*
import sample.*
import kotlin.native.concurrent.*

// 既然去掉了 Compose，我们先通过 NAPI 返回一个简单的标识，证明 Kotlin 代码已成功运行
@CName("getKotlinGreeting")
fun getKotlinGreeting(): String {
    return Greeting().greet() + " (HarmonyOS Native)"
}

@CName("getKotlinUiText")
fun getKotlinUiText(): String = ohosUiText()

fun ohosUiText(): String {
    val base = appInfo()
    val add = Arith.add(7, 3)
    val sub = Arith.sub(7, 3)
    return "$base\nAdd is $add, Sub is $sub"
}

@CName("getKotlinAnalyticsInfo")
fun getKotlinAnalyticsInfo(): String = analyticsInfo()

@CName("triggerKotlinHeapOverflow")
fun triggerKotlinHeapOverflow(): Int {
    val size = 16
    val ptr = malloc(size.convert())!!.reinterpret<ByteVar>()
    memset(ptr, 0, (size + 8).convert())
    val result = ptr[1].toInt()
    free(ptr)
    return result
}

@CName("triggerCpuFreeze")
fun triggerCpuFreeze(): Unit {
    println("Starting CPU Freeze for 10 seconds...")
    val startTime = time(null)
    // 强制阻塞 10 秒，确保触发 LIFECYCLE_TIMEOUT
    // 使用 volatile 防止编译器优化循环
    while (time(null) - startTime < 10) {
        // Busy loop
    }
    println("ArkTS Freeze Done")
}

@CName("triggerKotlinStackBufferOverflow")
fun triggerKotlinStackBufferOverflow(): Int = memScoped {
    println("triggerKotlinStackBufferOverflow called")
    val subscript = 43
    val buffer = allocArray<ByteVar>(42)
    buffer[subscript] = 42.toByte()
    println("address: $buffer")
    return@memScoped 0
}

@CName("triggerKotlinHeapUseAfterFree")
fun triggerKotlinHeapUseAfterFree(): Int {
    println("triggerKotlinHeapUseAfterFree called")
    val size = 32
    val ptr = malloc(size.convert())!!
    println("Allocated address: $ptr")
    free(ptr)
    println("Freed address, now trying to memset use-after-free...")
    // 释放后写入，使用 memset 防止编译器优化移除代码，且 memset 通常会被 ASAN 拦截检查
    memset(ptr, 0xEE, 1.convert())
    return 0
}

@CName("triggerKotlinNpe")
fun triggerKotlinNpe(): Int {
    println("triggerKotlinNpe called")
    val str: String? = null
    return str!!.length
}

@CName("triggerKotlinOutOfBounds")
fun triggerKotlinOutOfBounds(): Int {
    println("triggerKotlinOutOfBounds called")
    val list = listOf(1, 2, 3)
    return list[10]
}

@CName("triggerKotlinToCCrash")
fun triggerKotlinToCCrash(): Unit {
    println("triggerKotlinToCCrash called")
    trigger_c_crash()
}