package com.rc.core.util

import android.os.Environment
import android.util.Log
import java.io.*
import java.text.SimpleDateFormat
import java.util.*

/**
 * info
 *
 * @author ReiChin_
 */
object CrashHelper {

    private const val TAG = "LAB_Crash"

    /**
     * 自定义错误处理，收集错误信息，发送错误报告等操作均在此完成
     *
     * @param ex
     * @return true：如果处理了该异常信息；否则返回 false
     */
    fun handleException(ex: Throwable?): Boolean {
        if (ex == null) return false
        Log.e(TAG, "", ex)

        // 读取Error信息
        readThrowableInfo(ex)?.let { error ->
            // 保存日志文件
            saveCrashInfo2File(error, Environment.getExternalStorageDirectory())
        }
        return true
    }

    /**
     * 读取Throwable中的错误日志
     *
     * @param ex
     * @return
     */
    private fun readThrowableInfo(ex: Throwable): String? {
        var result: String? = null
        var writer: Writer? = null
        var printWriter: PrintWriter? = null
        try {
            writer = StringWriter()
            printWriter = PrintWriter(writer)
            ex.printStackTrace(printWriter)
            var cause = ex.cause
            while (cause != null) {
                cause.printStackTrace(printWriter)
                cause = cause.cause
            }
            result = writer.toString()
        } catch (e: Exception) {
            Log.e(TAG, "read throwable error....", e)
        } finally {
            printWriter?.let {
                it.close()
                printWriter = null
            }
            try {
                writer?.let {
                    it.close()
                    writer = null
                }
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
        return result
    }

    /**
     * 保存错误信息到文件中
     *
     * @param error
     * @return 返回文件名称, 便于将文件传送到服务器
     */
    fun saveCrashInfo2File(error: String, cacheDir: File): String? {
        val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
        val time = formatter.format(Calendar.getInstance().time)
        val sb = StringBuffer()
        sb.append(time + "\n")

        var fos: FileOutputStream? = null
        try {
            sb.append(error)
            sb.append("\n\n\n")

            val fileName = "error-${time}.log"
            if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {
                val errorFile = File(cacheDir, fileName)
                if (!errorFile.exists()) {
                    errorFile.createNewFile()
                }
                fos = FileOutputStream(errorFile)
                fos.write(sb.toString().toByteArray())
                fos.close()
            }

            return fileName
        } catch (e: Exception) {
            Log.e(TAG, "an error occured while writing file...", e)
        } finally {
            try {
                fos?.let {
                    it.close()
                    fos = null
                }
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }

        return null
    }

}