package com.zxhy.hfilemanagermaster.knife

import android.annotation.SuppressLint
import android.app.usage.StorageStatsManager
import android.content.Context
import android.os.Build
import android.os.storage.StorageManager
import android.os.storage.StorageVolume
import android.text.format.Formatter
import androidx.annotation.RequiresApi
import java.io.File
import java.lang.reflect.Field
import java.lang.reflect.Method
import java.util.UUID

/**
 * 计算储存介质
 */

const val TYPE_U = 0 //u盘
const val TYPE_DATA = 1 //data区域
const val TYPE_EXTERNAL = 2 //外置存储

data class Disk(
        val path: String = "", //路径
        val name: String = "", //名称
        val type: Int = 0,//类型 0U盘  1 data区域 2内置存储区域
        val total: Long = 0, //总计数量
        val used: Long = 0, //已用空间
        val free: Long = 0, //空闲空间
) {

    fun getTotalContent(context: Context): String {
        return Formatter.formatFileSize(context, total)
    }

    fun getUsedContent(context: Context): String {
        return Formatter.formatFileSize(context, used)
    }

    fun getFreeContent(context: Context): String {
        return Formatter.formatFileSize(context, free)
    }

}

@SuppressLint("SoonBlockedPrivateApi", "UsableSpace", "ObsoleteSdkInt", "DiscouragedPrivateApi")
fun Context.getMountInfoList(): List<Disk> {
    val diskList = arrayListOf<Disk>()
    val storageManager = getSystemService(Context.STORAGE_SERVICE) as StorageManager
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {//小于6.0
        val getVolumeListMethod = StorageManager::class.java.getDeclaredMethod("getVolumeList")
        val volumes = getVolumeListMethod.invoke(storageManager) as Array<StorageVolume>
        for (volume in volumes) {
            try {
                val fileMethod = volume.javaClass.getDeclaredMethod("getPathFile")
                val file = fileMethod.invoke(volume) as File
                val path = file.path
                val name = file.name
                val total = file.totalSpace //总计
                val used = total - file.freeSpace //空闲
                val usable = file.usableSpace //可用
                diskList.add(Disk(path, name, -1, total, used, usable))
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    } else {
        val getVolumeMethod = StorageManager::class.java.getDeclaredMethod("getVolumes")
        val volumes = getVolumeMethod.invoke(storageManager) as List<Any>
        for (volume in volumes) {
            try {
                val getTypeField: Field = volume.javaClass.getField("type")
                val type: Int = getTypeField.getInt(volume)
                val fileMethod = volume.javaClass.getDeclaredMethod("getPath")
                val f: File = fileMethod.invoke(volume) as File
                val path = f.path
                val name = f.name
                val total = if (type != TYPE_U && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    val getFsUuid: Method = volume.javaClass.getDeclaredMethod("getFsUuid")
                    val fsUuid = getFsUuid.invoke(volume) as? String
                    getTotalSize(fsUuid)
                } else {
                    f.totalSpace //总计
                }
                val used = total - f.usableSpace //空闲
                val usable = f.usableSpace //空闲
                val disk = Disk(path, name, type, total, used, usable)
                diskList.add(disk)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
    return diskList
}

@RequiresApi(Build.VERSION_CODES.O)
fun Context.getTotalSize(fsUuid: String?): Long {
    return try {
        val id = if (fsUuid == null) StorageManager.UUID_DEFAULT else UUID.fromString(fsUuid)
        val stats = getSystemService(StorageStatsManager::class.java)
        stats.getTotalBytes(id)
    } catch (e: Exception) {
        e.printStackTrace()
        -1
    }
}