package com.grkj.iscs.util

import android.content.Intent
import android.os.Process
import android.text.TextUtils
import com.grkj.iscs.MyApplication.Companion.instance
import com.grkj.iscs.util.FileUtil.CRASH_DIR
import com.grkj.iscs.util.FileUtil.getRootFolder
import com.grkj.iscs.util.log.LogUtil
import java.io.ByteArrayInputStream
import java.io.File
import java.io.FileNotFoundException
import java.io.FileOutputStream
import java.io.IOException
import java.io.PrintWriter
import java.io.StringWriter
import java.io.Writer
import kotlin.system.exitProcess

class MyCrashHandler : Thread.UncaughtExceptionHandler {
    override fun uncaughtException(t: Thread, e: Throwable) {
        LogUtil.e("程序出现异常了, Thread = ${t.name}, Throwable = ${e.message}")
        val stackTraceInfo = getStackTraceInfo(e)
        LogUtil.e("stackTraceInfo : $stackTraceInfo")
        saveThrowableMessage(stackTraceInfo)
        
        val ctx = instance!!.applicationContext
        val intent = ctx.packageManager.getLaunchIntentForPackage(ctx.packageName)
        intent!!.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        ctx.startActivity(intent)
        Process.killProcess(Process.myPid())
        exitProcess(0)
    }

    /**
     * 获取错误的信息
     *
     * @param throwable
     * @return
     */
    private fun getStackTraceInfo(throwable: Throwable): String {
        var pw: PrintWriter? = null
        val writer: Writer = StringWriter()
        try {
            pw = PrintWriter(writer)
            throwable.printStackTrace(pw)
        } catch (e: Exception) {
            return ""
        } finally {
            pw?.close()
        }
        return writer.toString()
    }

    //    private String logFilePath = Environment.getExternalStorageDirectory() + File.separator + "Android" +
    //            File.separator + "data" + File.separator + MyApplication.Companion.getInstance().getPackageName() + File.separator + "crashLog";
    private val logFilePath = getRootFolder(instance!!.applicationContext, 0)!!.absolutePath + CRASH_DIR

    private fun saveThrowableMessage(errorMessage: String) {
        if (TextUtils.isEmpty(errorMessage)) {
            return
        }
        val file = File(logFilePath)
        if (!file.exists()) {
            val mkdirs = file.mkdirs()
            if (mkdirs) {
                writeStringToFile(errorMessage, file)
            }
        } else {
            writeStringToFile(errorMessage, file)
        }
    }

    private fun writeStringToFile(errorMessage: String, file: File) {
        Thread {
            var outputStream: FileOutputStream? = null
            try {
                val inputStream = ByteArrayInputStream(errorMessage.toByteArray())
                outputStream =
                    FileOutputStream(File(file, System.currentTimeMillis().toString() + ".txt"))
                var len = 0
                val bytes = ByteArray(1024)
                while ((inputStream.read(bytes).also { len = it }) != -1) {
                    outputStream.write(bytes, 0, len)
                }
                outputStream.flush()
                LogUtil.e("程序出异常了, 写入本地文件成功：${file.absolutePath}")
            } catch (e: FileNotFoundException) {
                e.printStackTrace()
            } catch (e: IOException) {
                e.printStackTrace()
            } finally {
                if (outputStream != null) {
                    try {
                        outputStream.close()
                    } catch (e: IOException) {
                        e.printStackTrace()
                    }
                }
            }
        }.start()
    }
}