package com.base.filerecoveryrecyclebin.help

import com.base.filerecoveryrecyclebin.utils.LogEx
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.launch
import java.io.File
import java.io.IOException
import java.io.RandomAccessFile
import java.util.LinkedList


object FileHelp {

    private val TAG = "FileHelp"

    fun CoroutineScope.loadFileByFilter(
        flow1: MutableSharedFlow<String>? = null,
        flow2: MutableSharedFlow<Pair<Int, String>>? = null,
        folder: File,
        filter: (file: File) -> Boolean,
        onDo: ((file: File) -> Unit)? = null,
        onFinish: (() -> Unit)? = null
    ) = launch(Dispatchers.IO) {
        delay(1000)
        var size = 0

        //添加第一层文件到链表
        val linkList = LinkedList<File>()
        val fileList = folder.listFiles()
        fileList?.forEach {
            if (it.isDirectory) {
                linkList.add(it)
            } else {
                val flag = filter(it)
                LogEx.logDebug(TAG, "$it flag=$flag")
                if (flag) {
                    onDo?.invoke(it)
                    size++
                    flow2?.emit(Pair(size, it.absolutePath))
                }
                flow1?.emit(it.absolutePath)
            }
        }

        //链表取文件
        var tempFile: File
        while (!linkList.isEmpty()) {
            tempFile = linkList.removeFirst()
            val tempFileList = tempFile.listFiles()
            tempFileList?.forEach {
                if (it.isDirectory) {
                    linkList.add(it)
                } else {
                    val flag = filter(it)
//                    LogEx.logDebug(TAG, "$it flag=$flag")
                    if (flag) {
                        onDo?.invoke(it)
                        size++
                        flow2?.emit(Pair(size, it.absolutePath))
                    }
                    flow1?.emit(it.absolutePath)
                }
            }
        }
        onFinish?.invoke()
    }

    fun readFileRange(filePath: String, start: Long, end: Long): ByteArray {
        var data = byteArrayOf()
        try {
            val file = RandomAccessFile(filePath, "r")
            file.seek(start)
            val length = end - start
            data = ByteArray(length.toInt())
            file.readFully(data)
            file.close()
        } catch (e: IOException) {
            e.printStackTrace()
        }
        return data
    }

    fun getDirFiles(
        folder: File,
    ): ArrayList<File> {
        val result = arrayListOf<File>()
        //添加第一层文件到链表
        val linkList = LinkedList<File>()
        folder.listFiles()?.forEach {
            if (it.isDirectory) {
                linkList.add(it)
            } else {
                result.add(it)
            }
        }

        //链表取文件
        var tempFile: File
        while (!linkList.isEmpty()) {
            tempFile = linkList.removeFirst()
            val tempFileList = tempFile.listFiles()
            tempFileList?.forEach {
                if (it.isDirectory) {
                    linkList.add(it)
                } else {
                    result.add(it)
                }
            }
        }
        return result
    }

    fun getFileFolder(file: File): List<File> {

        val set = HashSet<File>()
        //添加第一层文件到链表
        val linkList = LinkedList<File>()
        val fileList = file.listFiles()
        fileList?.forEach {
            if (it.isDirectory) {
                linkList.add(it)
                set.add(it)
            }
        }

        //链表取文件
        var tempFile: File
        while (!linkList.isEmpty()) {
            tempFile = linkList.removeFirst()
            val tempFileList = tempFile.listFiles()
            tempFileList?.forEach {
                if (it.isDirectory) {
                    linkList.add(it)
                    set.add(it)
                }
            }
        }
        return set.toList()
    }

}