package net.taehui.twilight

import io.netty.handler.codec.DecoderException
import io.netty.handler.ssl.NotSslRecordException
import net.taehui.twilight.system.PlatformIDSystem
import org.apache.commons.codec.binary.Hex
import java.net.MalformedURLException
import java.net.SocketException
import java.net.URI
import java.security.MessageDigest
import java.util.*

object Utility {
    fun isEtcNetBundle(etc: String): Boolean {
        return etc.isNotEmpty() && "Qwilight" != etc && "MD5" != etc && !etc.contains(":")
    }

    fun getDistance(
        value: Component,
        waitBPMMap: Queue<Map.Entry<Double, Double>>,
        loopingCounter: Double,
        targetLoopingCounter: Double
    ): Double {
        var tmpLoopingCounter = loopingCounter
        var distance = 0.0
        while (!waitBPMMap.isEmpty()) {
            val (wait, bpm) = waitBPMMap.peek()
            if (wait < targetLoopingCounter) {
                distance += value.logicalYMillis * (wait - tmpLoopingCounter)
                tmpLoopingCounter = wait
                value.setBPM(bpm)
                waitBPMMap.poll()
            } else {
                break
            }
        }
        return distance + value.logicalYMillis * (targetLoopingCounter - tmpLoopingCounter)
    }

    fun getDefaultAvatarID(avatarID: String): String {
        return PlatformIDSystem.getAvatarID(avatarID.substring(avatarID.indexOf("@") + 1))
    }

    fun getFaultText(e: Throwable): String {
        return StringBuilder(e.localizedMessage ?: "").apply {
            e.stackTrace.forEach {
                append(System.lineSeparator())
                append(it)
            }
        }.toString()
    }

    fun getQuitStatusValue(point: Double, stand: Int): Int {
        if (point < 0.8) {
            return 6
        }
        if (point < 0.85) {
            return 5
        }
        if (point < 0.9) {
            return 4
        }
        if (point < 0.95) {
            return 3
        }
        return if (stand < 900000) 2 else if (point < 1.0) 1 else 0
    }

    fun isValidWww(www: String): Boolean {
        return try {
            return URI(www).isAbsolute
        } catch (e: MalformedURLException) {
            false
        }
    }

    fun isValidFault(e: Throwable): Boolean {
        return !(e is SocketException && e.localizedMessage?.contains("Connection reset") == true) && !(e is DecoderException && e.cause is NotSslRecordException)
    }

    fun getID512(noteFileData: ByteArray): String {
        val hashComputer = MessageDigest.getInstance("SHA-512")
        hashComputer.update(noteFileData)
        return Hex.encodeHexString(hashComputer.digest())
    }

    fun getID256(noteFileData: ByteArray): String {
        val hashComputer = MessageDigest.getInstance("SHA-256")
        hashComputer.update(noteFileData)
        return Hex.encodeHexString(hashComputer.digest())
    }

    fun getID128(noteFileData: ByteArray): String {
        val hashComputer = MessageDigest.getInstance("MD5")
        hashComputer.update(noteFileData)
        return Hex.encodeHexString(hashComputer.digest())
    }

    fun getNoteID512(noteID: String): String {
        return noteID.split(':')[0]
    }

    fun getDataID(noteID: String): Int {
        return noteID.split(':')[1].toInt()
    }
}