package com.fastcashier.lib_common.util

import android.content.Context
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.os.AsyncTask
import android.os.Environment
import android.util.Log
import com.fastcashier.lib_common.util.DateUtils
import com.fastcashier.lib_common.util.DateUtils.*
import java.io.*
import java.nio.charset.Charset
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.Executors

object LogFileUtils {
    private var logFiles //日志文件夹
            : File? = null
    private var logFile //单个日志文件
            : File? = null
    private val sExecutor = Executors.newSingleThreadExecutor()
    val CACHE_FILE_PATH = Environment
        .getExternalStorageDirectory().path +
            File.separator +
            "miyaterminal" +
            File.separator +
            "log" +
            File.separator
    val DAYS_INTERVAL_LOG_DELETE = 10 //本地log删除时间间隔
    var isProhibitWrite = false //是否禁止写入文件
    private var allFileBeanList //所有的文件列表
            : MutableList<FileBean>? = null
    private var deleteFilePathList //需要删除的文件列表
            : MutableList<File>? = null
    private const val logSuffix = ".txt"
    private const val logLink = "_"

    fun writeLog(c: Context, input: String): Boolean {
        sExecutor.execute { writeLogToFile(c, input) }
        return false
    }

    private fun writeLogToFile(context: Context, input: String) {
        var fos: FileOutputStream? = null
        var writer: OutputStreamWriter? = null
        try {
            logFiles = File(CACHE_FILE_PATH)
            if (!logFiles!!.exists()) {
                logFiles!!.mkdirs()
            }
            val logPath = (CACHE_FILE_PATH + getVersionCode(context)
                    + "_" + format8(Date()) + ".txt")
            logFile = File(logPath)
            fos = FileOutputStream(logFile, true)
            writer = OutputStreamWriter(fos, Charset.forName("utf-8"))
            writer.write(input)
            writer.flush()
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            try {
                writer?.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
            try {
                fos?.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }

    private fun getVersionCode(context: Context): String {
        val packageManager = context.packageManager
        val packageInfo: PackageInfo
        var versionCode = ""
        try {
            packageInfo = packageManager.getPackageInfo(context.packageName, 0)
            versionCode = packageInfo.versionCode.toString() + ""
        } catch (e: PackageManager.NameNotFoundException) {
            e.printStackTrace()
        }
        return versionCode
    }

    /**
     * 自动拼装时间戳的日志
     */
    fun writeLogFormat(c: Context, input: String): Boolean {
        val calendar = Calendar.getInstance()
        calendar.timeInMillis = System.currentTimeMillis()
        val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
        return writeLog(
            c, """${sdf.format(calendar.time)}	$input
"""
        )
    }

    /**
     * 写入throwable
     */
    fun writeThrowable(context: Context, throwable: Throwable?): Boolean {
        return try {
            if (throwable == null) {
                return false
            }
            val stringWriter = StringWriter()
            throwable.printStackTrace(PrintWriter(stringWriter))
            writeLogFormat(context, stringWriter.toString())
        } catch (e: Exception) {
            writeLogFormat(
                context,
                "error occur when writing throwable , error content is:" + e.message
            )
            false
        }
    }

    /**
     * 删除指定天数之前的日志，此处的天数不是精确到小时的，只精确到日
     *
     * @param days
     */
    fun deleteLog(days: Int) {
        files
        if (deleteFilePathList == null) {
            deleteFilePathList = ArrayList()
        } else {
            deleteFilePathList!!.clear()
        }
        if (allFileBeanList != null && allFileBeanList!!.size > 0) {
            for (i in allFileBeanList!!.indices) {
                getDeleteFileList(days, allFileBeanList!![i])
            }
        }
        if (deleteFilePathList != null && deleteFilePathList!!.size > 0) {
            val deleteFiles = deleteFilePathList!!.toTypedArray()
            DeleteLogTask().execute(*deleteFiles)
        }
    }

    /**
     * 执行符合条件的删除日志操作
     *
     * @param days
     * @param fileBean
     */
    private fun getDeleteFileList(days: Int, fileBean: FileBean) {
        val currentLongTimes = System.currentTimeMillis()
        if (fileBean.fileName!!.endsWith(logSuffix)) {
            if (fileBean.fileName!!.contains(logLink)) {
                try {
                    val fileNameWithOutSuffix =
                        fileBean.fileName!!.substring(0, fileBean.fileName!!.indexOf("."))
                    val fileNameDate = fileNameWithOutSuffix.substring(
                        fileNameWithOutSuffix.lastIndexOf(
                            logLink
                        ) + 1
                    )
                    val fileNameLongTimes =
                        stringToLong(fileNameDate, DF_YYYYMMDD)
                    if (currentLongTimes - fileNameLongTimes >= days * 24L * 60L * 60L * 1000L) { //符合要求，加入删除列表
                        deleteFilePathList!!.add(File(fileBean.filePath))
                    }
                } catch (e: ParseException) {
                    e.printStackTrace()
                }
            }
        }
    }

    /**
     * 获得日志文件夹下的文件名和文件路径
     */
    private val files: Unit
        private get() {
            if (allFileBeanList == null) {
                allFileBeanList = ArrayList()
            } else {
                allFileBeanList!!.clear()
            }
            val files = logFiles!!.listFiles()
            if (files != null) {
                for (i in files.indices) {
                    val fileBean = FileBean()
                    fileBean.fileName = files[i].name
                    fileBean.filePath = files[i].absolutePath
                    allFileBeanList!!.add(fileBean)
                }
            }
        }

    private fun doDeleteFiles(file: File) {
        //flie：要删除的文件夹的所在位置
        if (file.isDirectory) {
            val files = file.listFiles()
            for (i in files.indices) {
                val f = files[i]
                doDeleteFiles(f)
            }
            file.delete() //如要保留文件夹，只删除文件，请注释这行
        } else if (file.exists()) {
            file.delete()
        }
    }

    private class DeleteLogTask : AsyncTask<File, Void?, Boolean>() {
        override fun doInBackground(vararg files: File): Boolean {
            for (file in files) {
                doDeleteFiles(file)
            }
            return true
        }

        override fun onPostExecute(aBoolean: Boolean) {
            super.onPostExecute(aBoolean)
            if (aBoolean) {
                Log.i("LogFileUtils", "日志删除成功！")
            }
        }
    }

    private class FileBean {
        var fileName: String? = null
        var filePath: String? = null
    }
}