package com.duolebo.blyrobot.util

import android.app.ActivityManager
import android.content.Context
import android.text.TextUtils
import java.net.Inet4Address
import java.net.NetworkInterface
import java.util.*
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import java.io.*
import android.content.pm.PackageManager
import android.os.Build
import android.os.Environment
import java.util.regex.Pattern
import android.app.ActivityManager.RunningAppProcessInfo
import java.net.HttpURLConnection
import java.nio.file.Files.delete
import java.net.HttpURLConnection.HTTP_OK
import java.net.HttpURLConnection.setFollowRedirects
import java.net.URL
import android.R.attr.versionName
import android.content.pm.PackageInfo


object AppUtil {

    fun deleteFile(file: File?, fileFilter: FileFilter) {
        if (file == null) {
            return
        }
        if (!fileFilter.accept(file)) {
            return
        }
        if (file.isFile) {
            file.delete()
            return
        }
        val files = file.listFiles()
        if (files == null) {
            file.delete()
            return
        }
        for (childFile in files) {
            deleteFile(childFile, fileFilter)
        }
        file.delete()
    }

    fun getIPAddress(useIPv4: Boolean, interfaceName: String?): String {
        try {
            val interfaces = Collections.list(NetworkInterface.getNetworkInterfaces())
            for (intf in interfaces) {
                if (!TextUtils.isEmpty(interfaceName) && intf.name != interfaceName) {
                    continue
                }
                val addrs = Collections.list(intf.inetAddresses)
                for (addr in addrs) {
                    if (!addr.isLoopbackAddress) {
                        val sAddr = addr.hostAddress.toUpperCase()
                        //                        boolean isIPv4 = InetAddressUtils.isIPv4Address(sAddr);
                        val isIPv4 = addr is Inet4Address //Since API-23 InetAddressUtils was removed
                        if (useIPv4) {
                            if (isIPv4)
                                return sAddr
                        } else {
                            if (!isIPv4) {
                                val delim = sAddr.indexOf('%') // drop ip6 port suffix
                                return if (delim < 0) sAddr else sAddr.substring(0, delim)
                            }
                        }
                    }
                }
            }
        } catch (ex: Exception) {
        }
        // for now eat exceptions
        return ""
    }

    fun pngToJpg(pngFilePath: String, jpgFilePath: String) {
        val bitmap = BitmapFactory.decodeFile(pngFilePath)
        try {
            val fos = FileOutputStream(jpgFilePath)
            BufferedOutputStream(fos).use { bos ->
                if (bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos)) {
                    bos.flush()
                }
                bos.close()
            }
            fos.close()
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            bitmap!!.recycle()
        }
    }

    fun cropImage(imagePath: String){
        val bitmap = BitmapFactory.decodeFile(imagePath)
        try {
            val height = bitmap.height
            val cropBitmap = Bitmap.createBitmap(bitmap, 0, height - 100, bitmap.width, 100)
            val index = imagePath.lastIndexOf('.')
            val partName = imagePath.substring(0, index)
            val newPath = partName + "_ocr.jpg"
            val file = File(newPath)

            val fos = FileOutputStream(file)
            BufferedOutputStream(fos).use { bos ->
                if (cropBitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos)) {
                    bos.flush()
                }
                bos.close()
            }
            fos.close()

            cropBitmap?.recycle()
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            bitmap!!.recycle()
        }
    }

    fun readFromLocal(file: File): String {
        var res = ""
        if (file.isFile && file.exists()) {
            try {
                val fis = FileInputStream(file)
                res = fileRead(fis)
                fis.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }

        }

        return res
    }

    fun fileRead(fis: InputStream): String {
        val baos = ByteArrayOutputStream()
        val buffer = ByteArray(1024)
        var len: Int
        try {
            len = fis.read(buffer)
            while (len != -1) {
                baos.write(buffer, 0, len)
                len = fis.read(buffer)
            }
        } catch (e: IOException) {
            e.printStackTrace()
        }

        val result = String(baos.toByteArray())
        try {
            baos.close()
            fis.close()
        } catch (e: IOException) {
            e.printStackTrace()
        }

        return result
    }

    fun readFromAssert(context: Context, fileName: String): String {
        var res = ""
        try {
            val inputStream = context.assets.open(fileName)
            res = fileRead(inputStream)
            inputStream.close()
        } catch (e: IOException) {
            // TODO Auto-generated catch block
            e.printStackTrace()
        }

        return res
    }

    fun isAppInstalled(context: Context, uri: String): Boolean {
        val pm = context.packageManager
        var installed: Boolean
        installed = try {
            pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES)
            true
        } catch (e: PackageManager.NameNotFoundException) {
            false
        }

        return installed
    }

    fun getAbsoluteSdcardPath(): String {
        var sdcardAbsPath = ""
        if (TextUtils.isEmpty(sdcardAbsPath))
            sdcardAbsPath = Environment.getExternalStorageDirectory().absolutePath

        // 4.2系统存在legacy|0读取问题
//        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN_MR1) {
//            sdcardAbsPath = "/sdcard"
//        }

        val p = Pattern.compile("/?storage/emulated/\\d{1,2}")
        val m = p.matcher(sdcardAbsPath)
        if (m.find()) {
            sdcardAbsPath = sdcardAbsPath.replace("storage/emulated/0", "storage/emulated/legacy")
        }

        return sdcardAbsPath
    }

    fun isAppForeground(context: Context, packageName: String): Boolean {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            return AdbUtil.isAppActive(packageName)
        }

        val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        val appProcesses = activityManager.runningAppProcesses
        for (appProcess in appProcesses) {
            if (appProcess.processName == packageName) {
                return appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND
            }
        }
        return false
    }

    fun saveToFile(fileName: String, content: String) {
        try {
            val fw = FileWriter(File(fileName))
            fw.write(content)
            fw.close()
        } catch (e: FileNotFoundException) {
            e.printStackTrace()
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

    fun existsUrl(url: String): Boolean {
        return try {
            HttpURLConnection.setFollowRedirects(false)
            val con = URL(url).openConnection() as HttpURLConnection
            con.requestMethod = "HEAD"
            con.responseCode == HttpURLConnection.HTTP_OK
        } catch (e: Exception) {
            e.printStackTrace()
            false
        }
    }

    fun getVersionName(context: Context, packageName: String): String {
        val manager = context.packageManager
        var name = ""
        try {
            val info = manager.getPackageInfo(packageName, 0)
            name = info.versionName
        } catch (e: PackageManager.NameNotFoundException) {
            e.printStackTrace()
        }

        return name
    }

    fun clearCache() {
        val path = getAbsoluteSdcardPath() + "/upload/"
        val dir = File(path)
        if (dir.exists()) {
            for (subDir in dir.listFiles()) {
                if (subDir.isDirectory) {
                    for (file in subDir.listFiles()) {
                        file.delete()
                    }
                }
            }
        }
    }
}