package somecodes

import java.io.File
import kotlin.io.path.Path

@Suppress("unused")
class Codes {

    companion object{
        val audioFilePath = Path(System.getProperty("user.dir"), "audiofile")
        private val validAudioExtensions = setOf("wav", "mp3")
        private val KB_size = 1024 // 1 KB = 1024 bytes
        private val MB_size = 1024 * KB_size // 1 MB = 1024 KB
        private val GB_size = 1024 * MB_size // 1 GB = 1024 MB

        fun SizeToString(size: Long) : String {
            return when {
                size >= GB_size -> String.format("%.2f GB", size.toDouble() / GB_size)
                size >= MB_size -> String.format("%.2f MB", size.toDouble() / MB_size)
                size >= KB_size -> String.format("%.2f KB", size.toDouble() / KB_size)
                else -> "$size bytes"
            }
        }
        fun getAudioFiles() : Array<String> {
            val audioDir = audioFilePath.toFile()
            if (!audioDir.exists()) {
                audioDir.mkdirs() // Create directory if it doesn't exist
            }
            val ll = audioDir.listFiles()?.filter { it.isFile && validAudioExtensions.contains(it.extension) }?.map { it.name } ?: emptyList()
            return ll.toTypedArray()
        }

        fun getaudioFileFullPath(filename: String) : String {
            if (ValidString(filename)) {
                val file = audioFilePath.resolve(filename)
                return file.toAbsolutePath().toString()
            }
            return ""
        }

        fun ValidFile(s: String?) : Boolean {
            if (s!=null){
                if (ValidString(s)){
                    val ff = File(s)
                    return ff.isFile
                }
            }
            return false
        }

        fun ValidString(s : String?) : Boolean {
            return s != null && s.isNotEmpty() && s.isNotBlank()
        }

        /**
         * Codec header for Zello audio packet is base64 encoded string from {samplingrate (16 Little Endian), frames_per_packet, frame_size_ms}
         * @param samplingrate Sampling rate in Hz (e.g., 8000, 16000, 32000, etc.)
         * @param frames_per_packet Number of frames per packet (usually 1 or 2)
         * @param frame_size_ms Size of each frame in milliseconds (e.g., 20, 30, 40, etc.)
         */
        fun toCodecHeader(samplingrate: Int, frames_per_packet: Byte, frame_size_ms: Byte) : String{
            val xx = ByteArray(4)
            xx[0] = (samplingrate and 0xFF).toByte() // Little Endian
            xx[1] = ((samplingrate shr 8) and 0xFF).toByte()
            xx[2] = frames_per_packet
            xx[3] = frame_size_ms
            return java.util.Base64.getEncoder().encodeToString(xx)
        }

        fun fromCodecHeader(header: String) : Triple<Int, Byte, Byte>? {
            val decoded = java.util.Base64.getDecoder().decode(header)
            if (decoded.size != 4) return null
            val samplingrate = (decoded[0].toInt() and 0xFF) or ((decoded[1].toInt() and 0xFF) shl 8)
            val frames_per_packet = decoded[2]
            val frame_size_ms = decoded[3]
            return Triple(samplingrate, frames_per_packet, frame_size_ms)
        }
    }
}