package com.develop.base.util

import android.content.ContentUris
import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.DocumentsContract
import android.provider.MediaStore
import java.io.*


object FileKit {

    fun ensureFolder(filePath: String) {
        val file = File(filePath)
        if (!file.exists()) {
            file.mkdirs()
        }
    }

    fun copyUriToDst(context: Context, srcUri: Uri, dst: File) {
        val bytes = ByteArray(1024)
        val inputStream = context
            .contentResolver
            .openInputStream(srcUri)!!
        val outputStream = FileOutputStream(dst)
        while (inputStream.read(bytes) != -1) {
            outputStream.write(bytes)
        }
        inputStream.close()
        outputStream.close()
    }

    fun readFileToString(file: File): String {
        val sb = StringBuilder()
        try {
            //打开文件输入流
            val inputStream = FileInputStream(file)
            val buffer = ByteArray(1024)
            var len: Int = inputStream.read(buffer)
            //读取文件内容
            while (len > 0) {
                sb.append(String(buffer, 0, len))
                //继续将数据放到buffer中
                len = inputStream.read(buffer)
            }
            //关闭输入流
            inputStream.close()
        } catch (ex: Exception) {
            ex.printStackTrace()
        }
        return sb.toString()
    }

    fun writeToFile(file: File, content: String) {
        try {
            val out = BufferedWriter(FileWriter(file))
            out.write(content)
            out.close()
        } catch (ex: Exception) {
            ex.printStackTrace()
        }
    }


    fun deleteFile(filePath: String?): Boolean {
        if (filePath == null)
            return false
        val file = File(filePath)
        if (!file.exists()) {
            return false
        }
        return file.delete()
    }

    /**
     * 拷贝assets文件
     */
    fun copyAssetsFile(context: Context, srcFilePath: String, desFilePath: String): Boolean {
        val desFile = File(desFilePath)
        try {
            if (desFile.exists()) {
                desFile.delete()
            }
            desFile.createNewFile()
            var input: InputStream? =
                context.applicationContext.assets.open(srcFilePath) ?: return false
            var out: OutputStream? = FileOutputStream(desFile)
            val buffer = ByteArray(4096)
            var n: Int
            var sum = 0
            while ((input?.read(buffer) ?: 0).also { n = it } > 0) {
                sum += n
                out?.write(buffer, 0, n)
                out?.flush()
            }
            input?.close()
            input = null
            out?.close()
            out = null
        } catch (e: IOException) {
            e.printStackTrace()
            desFile.delete()
            return false
        }
        return true
    }


    /**
     * Get a file path from a Uri. This will get the the path for Storage Access
     * Framework Documents, as well as the _data field for the MediaStore and
     * other file-based ContentProviders.
     *
     * @param context The context.
     * @param uri     The Uri to query.
     * @author paulburke
     */
    fun getPath(context: Context, uri: Uri): String? {

        // DocumentProvider
        if (DocumentsContract.isDocumentUri(context, uri)) {
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {
                val docId = DocumentsContract.getDocumentId(uri)
                val split = docId.split(":").toTypedArray()
                val type = split[0]
                if ("primary".equals(type, ignoreCase = true)) {
                    return Environment.getExternalStorageDirectory().toString() + "/" + split[1]
                }
            } else if (isDownloadsDocument(uri)) {
                // DownloadsProvider
                val id = DocumentsContract.getDocumentId(uri)
                val contentUri = ContentUris.withAppendedId(
                    Uri.parse("content://downloads/public_downloads"), java.lang.Long.valueOf(id)
                )
                return getDataColumn(context, contentUri, null, null)
            } else if (isMediaDocument(uri)) {
                // MediaProvider
                val docId = DocumentsContract.getDocumentId(uri)
                val split = docId.split(":").toTypedArray()
                val type = split[0]
                var contentUri: Uri? = null
                when (type) {
                    "image" -> {
                        contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
                    }
                    "video" -> {
                        contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
                    }
                    "audio" -> {
                        contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
                    }
                }
                val selection = "_id=?"
                val selectionArgs = arrayOf(
                    split[1]
                )
                return getDataColumn(context, contentUri, selection, selectionArgs)
            }
        } else if ("content".equals(uri.scheme, ignoreCase = true)) {
            // MediaStore (and general)  // Return the remote address
            return if (isGooglePhotosUri(uri)) {
                uri.lastPathSegment
            } else getDataColumn(context, uri, null, null)
        } else if ("file".equals(uri.scheme, ignoreCase = true)) {
            // File
            return uri.path
        }
        return null
    }

    /**
     * *
     * Get the value of the data column for this Uri. This is useful for
     * MediaStore Uris, and other file-based ContentProviders.
     *
     * @param context       The context.
     * @param uri           The Uri to query.
     * @param selection     (Optional) Filter used in the query.
     * @param selectionArgs (Optional) Selection arguments used in the query.
     * @return The value of the _data column, which is typically a file path.
     */
    private fun getDataColumn(
        context: Context, uri: Uri?, selection: String?,
        selectionArgs: Array<String>?
    ): String? {
        var cursor: Cursor? = null
        val column = "_data"
        val projection = arrayOf(
            column
        )
        try {
            cursor = context.contentResolver.query(
                uri!!, projection, selection, selectionArgs,
                null
            )
            if (cursor != null && cursor.moveToFirst()) {
                val index: Int = cursor.getColumnIndexOrThrow(column)
                return cursor.getString(index)
            }
        } finally {
            cursor?.close()
        }
        return null
    }


    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    private fun isExternalStorageDocument(uri: Uri): Boolean {
        return "com.android.externalstorage.documents" == uri.authority
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    private fun isDownloadsDocument(uri: Uri): Boolean {
        return "com.android.providers.downloads.documents" == uri.authority
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    private fun isMediaDocument(uri: Uri): Boolean {
        return "com.android.providers.media.documents" == uri.authority
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    fun isGooglePhotosUri(uri: Uri): Boolean {
        return "com.google.android.apps.photos.content" == uri.authority
    }

}