package com.stand.standapp.utils

import android.content.Context
import timber.log.Timber

object AppKiller {

    private var isKilling = false

    fun killApp(context: Context, isCrash: Boolean = false, restart: Boolean = false) {
        if (isKilling) return
        isKilling = true
        
        Timber.tag("AppKiller").i("Starting app cleanup. isCrash: $isCrash, restart: $restart")

        try {
            GpioManager.stopListening()
            Timber.tag("AppKiller").i("GPIO stopped")
        } catch (e: Exception) {
            Timber.tag("AppKiller").e(e, "GPIO stop failed")
        }

        try {
            com.example.kingway.ptt.SendAtUtil.toCancelLogin()
            com.example.kingway.ptt.SendAtUtil.toLogout()
            Timber.tag("AppKiller").i("PTT logged out")
        } catch (e: Exception) {
            Timber.tag("AppKiller").e(e, "PTT logout failed")
        }

        try {
            com.stand.standapp.printer.PrinterManager.getFactory()?.ClosePort()
            Timber.tag("AppKiller").i("Printer port closed")
        } catch (e: Exception) {
            Timber.tag("AppKiller").e(e, "Printer close failed")
        }

        Timber.tag("AppKiller").i("Cleanup finished. Killing process.")

        if (!isCrash) {
            try {
                Thread.sleep(50)
            } catch (e: Exception) {}
        }

        try {
            // LogManager.shutdown() 会关闭其内部的线程池
            // 调用后绝对不能再使用 Timber 打印日志，否则会抛出 RejectedExecutionException 导致死循环
            LogManager.shutdown()
        } catch (e: Exception) {}

        if (restart) {
            try {
                val intent = context.packageManager.getLaunchIntentForPackage(context.packageName)
                if (intent != null) {
                    intent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK or android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK)
                    val flags = android.app.PendingIntent.FLAG_ONE_SHOT or android.app.PendingIntent.FLAG_IMMUTABLE
                    val pendingIntent = android.app.PendingIntent.getActivity(context, 223344, intent, flags)
                    val mgr = context.getSystemService(Context.ALARM_SERVICE) as android.app.AlarmManager
                    mgr.set(android.app.AlarmManager.RTC, System.currentTimeMillis() + 100, pendingIntent)
                }
            } catch (e: Exception) {}
        }

        android.os.Process.killProcess(android.os.Process.myPid())
        System.exit(0)
    }

    fun setupUncaughtExceptionHandler(context: Context) {
        val defaultHandler = Thread.getDefaultUncaughtExceptionHandler()
        Thread.setDefaultUncaughtExceptionHandler { thread, throwable ->
            Timber.tag("AppKiller").e(throwable, "Uncaught exception detected! Force cleanup.")
            killApp(context, true)
            defaultHandler?.uncaughtException(thread, throwable)
        }
    }
}
